Author SHA1 Message Date
evgeny ef34f81c90 Document device group implementation requirements 2026-11-02 16:17:03 +01:00
evgeny 26f8491abc Add missing desktop voice compressor controls 2026-11-02 16:17:03 +01:00
evgeny 1c0f40f247 Accept zero compressor gain and clarify Android storage limits 2026-11-02 16:17:03 +01:00
evgeny 2260719ff7 Add signed Android release build scripts 2026-11-02 15:03:46 +01:00
evgeny 3166ee7a41 Remove unused log file field from Android settings 2026-11-02 15:03:45 +01:00
evgeny 2b5b5aad88 Fix group JOIN retry delays after rejection and transport failure 2026-11-02 00:33:55 +01:00
evgeny ba6306f396 Give independent stream test an explicit BGP group owner 2026-11-01 23:24:14 +01:00
evgeny 2414207e80 Document online requirement for opening stream subscriptions 2026-11-01 23:23:44 +01:00
evgeny d87fb7c555 Clarify BGP availability and source watcher documentation 2026-11-01 23:23:25 +01:00
evgeny 9b416fad82 Test BGP stream availability, recovery and offline viewer cleanup 2026-11-01 23:22:48 +01:00
evgeny 5b5a5e94e3 Remove offline Android streams without draining playback 2026-11-01 23:21:39 +01:00
evgeny 83f6a79985 Report offline stream sources in Android playback 2026-11-01 23:21:39 +01:00
evgeny bf63f79fdf Show offline stream closure in the desktop player 2026-11-01 23:10:27 +01:00
evgeny 46a5cf14ce Close stream receivers when their source goes offline in BGP 2026-11-01 23:10:00 +01:00
evgeny 2f94da7bbf Test Android stream audio switching and cleanup ownership 2026-11-01 23:06:32 +01:00
evgeny 2b268f314f Switch Android playback clocks when stream audio changes 2026-11-01 23:05:57 +01:00
evgeny 4e28c518bd Verify remote no-audio readiness independently of the audio buffer 2026-11-01 22:52:18 +01:00
evgeny 827f3dc619 Declare source audio state in live playback and drain fixtures 2026-11-01 22:48:36 +01:00
evgeny cbe4cb1e33 Use video playback clocks when the source disables audio 2026-11-01 22:48:19 +01:00
evgeny 0bd046adca Reserve telemetry width for playback catch-up speed 2026-11-01 22:29:29 +01:00
evgeny b414fc9538 Verify the bottom player bar and logarithmic volume output 2026-11-01 22:23:49 +01:00
evgeny 5a8807bf89 Keep multiview captions and controls below video and use logarithmic volume 2026-11-01 22:23:09 +01:00
evgeny 213a1010c2 Move live player controls below video with a triangular volume scale 2026-11-01 22:22:44 +01:00
evgeny c91782848f Use the red crossed microphone for the no-audio source selection 2026-11-01 22:11:35 +01:00
evgeny 515645dac5 Cross out the red microphone icon when stream audio is off 2026-11-01 22:10:25 +01:00
evgeny a2d700d5a6 Show the same microphone icon in red when stream audio is off 2026-11-01 22:09:39 +01:00
evgeny 44b7efb1ce Show microphone mute icons on the stream audio button 2026-11-01 22:05:41 +01:00
evgeny fabc76ef82 Keep microphone and no-audio options available during publication 2026-11-01 22:05:10 +01:00
evgeny 3eff460457 Allow desktop stream audio to be enabled and disabled live 2026-11-01 22:04:23 +01:00
evgeny 1a113f953b Verify video continues after microphone samples stop 2026-11-01 21:56:31 +01:00
evgeny f7096bba7d Continue streaming without audio after a 300 ms microphone timeout 2026-11-01 21:54:47 +01:00
evgeny 83183f9885 Test live microphone changes and video-only startup 2026-11-01 21:42:45 +01:00
evgeny 1a413608ca Start desktop streams without audio when capture is unavailable 2026-11-01 21:39:26 +01:00
evgeny 1719f8e108 Save shared stream microphone through the main window 2026-11-01 21:38:36 +01:00
evgeny fbc030dc5b Share radio microphone controls with desktop publication 2026-11-01 21:38:01 +01:00
evgeny b2bd2c284c Use shared microphone selection for live desktop streams 2026-11-01 21:37:37 +01:00
evgeny 4338f1f9c8 Skip Windows drive roots when creating attachment directories 2026-11-01 21:30:23 +01:00
evgeny 8e204ef887 Log precise directory creation errors when preparing attachments 2026-11-01 21:02:47 +01:00
evgeny 8074b73e95 Verify blocked Bluetooth device close through the actual WinRT cleanup path 2026-11-01 20:49:44 +01:00
evgeny 27d51e93b7 Update diagnostic filters, codec regression and BLE debugging instructions 2026-11-01 20:41:02 +01:00
evgeny 8336487596 Move desktop video and publisher diagnostics out of temporary debug category 2026-11-01 20:40:13 +01:00
evgeny 811f5b7659 Keep packet reception and FFmpeg diagnostics in their module categories 2026-11-01 20:40:13 +01:00
evgeny b0fe663109 Move ETCP packet and carrier diagnostics from debug to etcp trace 2026-11-01 20:39:35 +01:00
evgeny 8ca7c3cc15 Trace BLE cleanup phases and distinguish closing from completed teardown 2026-11-01 20:39:07 +01:00
evgeny 0308d4a702 Add independent diagnostics for stalled BLE WinRT cleanup calls 2026-11-01 20:37:44 +01:00
evgeny d7e5672261 Record capture shutdown verification and pending Windows device check 2026-11-01 20:31:12 +01:00
evgeny fff072d0a8 Identify capture process failures and record forced exits accurately 2026-11-01 20:30:22 +01:00
evgeny 95425aacab Defer capture rollback and bind errors to the failed configuration 2026-11-01 20:27:17 +01:00
evgeny 96e4c72027 Align stream preview documentation with isolated CPU capture 2026-11-01 20:25:57 +01:00
evgeny 05e1b1e037 Verify rollback continuity and enumerate test windows through capture IPC 2026-11-01 20:25:14 +01:00
evgeny 093d8f15e4 Check asynchronous missing-camera errors in publisher tests 2026-11-01 20:20:23 +01:00
evgeny 006d45024b Make capture cleanup idempotent and identify frame release stalls 2026-11-01 20:20:00 +01:00
evgeny caf4ab406c Document isolated stream capture shutdown and diagnostics 2026-11-01 20:18:34 +01:00
evgeny 8c2289b188 Preserve call camera geometry before stream orientation transforms 2026-11-01 20:17:15 +01:00
evgeny 14bdd2a58f Pass only immutable source identifiers into the publisher 2026-11-01 20:15:42 +01:00
evgeny 61663e261d Keep capture lifecycle diagnostics in the video category 2026-11-01 20:15:03 +01:00
evgeny cf356ee647 Refresh capture devices through IPC and diagnose unexpected backend stops 2026-11-01 20:14:07 +01:00
evgeny 8faaa34e24 Complete capture API migration and cancel prelaunch stop requests 2026-11-01 20:13:07 +01:00
evgeny 939f33773b Verify capture timeout diagnostics and large-frame ownership 2026-11-01 20:11:12 +01:00
evgeny b34825cda0 Exercise hung capture stop and destruction without blocking publisher GUI 2026-11-01 20:10:31 +01:00
evgeny 4ab0be1882 Test stream UI with process-owned sources and CPU previews 2026-11-01 20:08:58 +01:00
evgeny a02465217b Keep capture completion observable and retain session ownership through stop 2026-11-01 20:08:01 +01:00
evgeny eed07cb358 Feed publisher CPU frames and decouple FIN from capture teardown 2026-11-01 20:06:56 +01:00
evgeny 5256dfa8c5 Use shared capture worker for calls and build screen backends there 2026-11-01 20:04:50 +01:00
evgeny e299a9b30b Isolate screen capture lifecycle and report worker close stages 2026-11-01 20:04:13 +01:00
evgeny 48998b440f Extract shared video capture process contracts 2026-11-01 20:02:12 +01:00
evgeny e384d4cf3d Add desktop network traffic graphs and unify microphone icons 2026-11-01 14:45:01 +01:00
evgeny 3dff681ff0 Unify channel action icons and add a drawn settings gear 2026-11-01 10:54:41 +01:00
evgeny a77a41f068 Refine composer icons with consistent vector outlines 2026-11-01 10:29:16 +01:00
evgeny 46b3296a36 Match composer microphone and attachment icons to Android 2026-11-01 10:10:49 +01:00
evgeny c889928e52 Show FFmpeg driver errors when hardware encoding fails 2026-11-01 08:24:43 +01:00
evgeny d8db018166 Focus the message input when the chat window is activated 2026-11-01 05:49:06 +01:00
evgeny 4e3c1182db Offer JPEG and PNG clipboard attachments with automatic selection 2026-10-31 22:30:57 +01:00
evgeny 4d30fa6bcc Support pasting clipboard images as PNG attachments 2026-10-31 22:13:11 +01:00
evgeny c8012d35f1 Limit ETCP TCP link MTU to 1500 bytes 2026-10-31 21:35:10 +01:00
evgeny 57168e4a16 Update startup regression for skipped automatic TCP listeners 2026-10-31 20:12:08 +01:00
evgeny c8388ba8ba Cover IPv6 bind failure and offline startup in socket regressions 2026-10-31 20:08:26 +01:00
evgeny 84e26dcf00 Test automatic socket failures and recovery without startup rollback 2026-10-31 20:07:16 +01:00
evgeny 60af36902c Skip unavailable automatic sockets and retain working transports 2026-10-31 20:06:17 +01:00
evgeny 4f2ad13e39 Preserve socket bind errors through resource cleanup 2026-10-31 20:05:46 +01:00
evgeny 5b531ddae7 Improve Android proximity settings and channel scanner layout 2026-10-31 18:29:09 +01:00
evgeny 2c89490794 Cover maximized media restoration and destruction during playback 2026-10-31 18:03:26 +01:00
evgeny 4764a7dd23 Restore the normal media rectangle explicitly when leaving fullscreen 2026-10-31 18:02:16 +01:00
evgeny 8ab294fb30 Fit media frames inside monitors and close video before widget teardown 2026-10-31 18:01:41 +01:00
evgeny 703f4a4a60 Keep complete diagnostics for media monitor restoration failures 2026-10-31 18:00:16 +01:00
evgeny 68065d4a79 Document viewer geometry ownership and gate the offscreen monitor fixture 2026-10-31 17:58:34 +01:00
evgeny 6a1b7c5363 Verify media geometry survives restarts on each physical monitor 2026-10-31 17:57:56 +01:00
evgeny db1c2f0da7 Test cached media geometry and stable video windows across file loads 2026-10-31 17:56:34 +01:00
evgeny c0d5aac41c Use explicit wide bounds when restoring media coordinates 2026-10-31 17:55:06 +01:00
evgeny 2a0374e2ae Persist shared chat media geometry and the physical monitor per profile 2026-10-31 17:53:16 +01:00
evgeny 1d9570e38b Keep video playback geometry and use the actual fullscreen state 2026-10-31 17:51:48 +01:00
evgeny 74d95bc9c4 Preserve shared PTT ownership on panel cleanup and avoid repeated reset logs 2026-10-31 17:32:25 +01:00
evgeny 165f5e6c63 Test the shared lock indicator and unlocking PTT across input sources 2026-10-31 17:32:13 +01:00
evgeny d25d097287 Let the hotkey toggle the common PTT latch without a second latch state 2026-10-31 17:31:24 +01:00
evgeny 3d0f3213f8 Display and release the shared PTT latch from the radio button 2026-10-31 17:30:54 +01:00
evgeny febaf3d350 Store the shared button and keyboard PTT latch in the radio engine 2026-10-31 17:30:38 +01:00
evgeny 4b23fa2b63 Verify hotkey double-press preference survives reopening settings 2026-10-31 17:22:02 +01:00
evgeny 80935eb2a5 Exercise global PTT polling and checkbox independence under X11 2026-10-31 17:21:03 +01:00
evgeny 99f4121a31 Translate the single PTT hotkey and double-press option 2026-10-31 17:20:25 +01:00
evgeny 83f16d8dcd Cover single portal assignment and optional hotkey locking 2026-10-31 17:19:56 +01:00
evgeny d1a62c51ef Persist optional double-press locking for the radio hotkey 2026-10-31 17:19:23 +01:00
evgeny 11e9946549 Show one radio shortcut and a hotkey double-press checkbox 2026-10-31 17:19:11 +01:00
evgeny 497ecd5d15 Register one Wayland PTT shortcut and reset latches on session changes 2026-10-31 17:17:31 +01:00
evgeny 239c4f7a7a Use one global PTT shortcut with double-press latching 2026-10-31 17:17:04 +01:00
evgeny a708e9494a Add single PTT hotkey hold and double-press state 2026-10-31 17:16:30 +01:00
evgeny 170ccf5db6 Fix Windows camera error encoding and add camera context 2026-10-31 16:08:44 +01:00
evgeny a7da1e3286 Preserve Windows camera error text with UTF-8 code page 2026-10-31 15:35:46 +01:00
evgeny db414a0042 Record successful Windows BLE GATT profile radio probe 2026-10-31 14:38:09 +01:00
evgeny 51a0e3f9f2 Use one GATT advertisement and read full BLE node profiles 2026-10-31 14:35:37 +01:00
evgeny 5d265dbd28 Cancel queued Android BLE sends after link closure 2026-10-31 12:20:47 +01:00
evgeny f3813b1a56 Show available receive buffer headroom in call audio graphs 2026-10-31 10:48:06 +01:00
evgeny ee0c92b9d8 Fix delayed router epoch confirmation and collapse duplicate BLE links 2026-10-31 10:22:22 +01:00
evgeny 0915c8ad2e Stabilize call batching and sole BLE retransmission timing 2026-10-31 09:12:18 +01:00
evgeny 92a58fe285 Speed up Windows installer compression 2026-10-31 01:03:03 +01:00
evgeny 2d92a003fc Keep connection property changes from refreshing BLE discovery 2026-10-31 00:53:11 +01:00
evgeny 2c2fd09323 Seed cached BlueZ service identities without refreshing discovery age 2026-10-31 00:51:54 +01:00
evgeny 17c22eb562 Verify one BlueZ advertisement and independent visibility and admission 2026-10-31 00:40:59 +01:00
evgeny d00a642c49 Define BLE v5 visibility, admission and bounded publication contracts 2026-10-31 00:37:11 +01:00
evgeny 5deb6de7ee Verify canonical UUID conversion across WinRT GUID byte order 2026-10-31 00:36:16 +01:00
evgeny 67a76b4119 Test and probe Windows single-provider discovery lifecycle 2026-10-31 00:35:56 +01:00
evgeny de600c56e9 Bind BlueZ discovery and characteristic selection to node service UUIDs 2026-10-31 00:35:23 +01:00
evgeny 8a5a423da9 Use a single connectable node service advertisement on Windows 2026-10-31 00:33:44 +01:00
evgeny 0b66ec27d2 Discover and select Android BLE peers by their service UUID 2026-10-31 00:32:26 +01:00
evgeny 1e4fca0b25 Encode BLE node identity in versioned GATT service UUIDs 2026-10-31 00:31:23 +01:00
evgeny 56a24c589f Document confirmed Windows beacon and GATT addressing mismatch 2026-10-31 00:27:42 +01:00
evgeny ea98964a89 Log BLE endpoint connectability before Android GATT attempts 2026-10-31 00:23:37 +01:00
evgeny c200fd0cf2 Record verified invitation fixes for rotated addresses and reused MTU 2026-10-31 00:00:53 +01:00
evgeny 79064380cb Document verified BLE bootstrap protocol and frame contracts 2026-10-31 00:00:36 +01:00
evgeny 6bb9a9c14d Verify challenge retries keep the original opening deadline 2026-10-31 00:00:15 +01:00
evgeny 01af2df02b Accept full GATT RX when reused ACL has unknown TX MTU 2026-10-30 23:58:52 +01:00
evgeny 3124c82bd4 Add reproducible hardware invitation delivery probe 2026-10-30 23:57:29 +01:00
evgeny 563203056d Cover private address rotation and unrelated connected peers 2026-10-30 23:54:27 +01:00
evgeny 6c947ac057 Reuse connected BlueZ peer across private address rotation 2026-10-30 23:53:59 +01:00
evgeny e25a8464f2 Bound challenge replacement and test large profiles and cancellation 2026-10-30 23:46:00 +01:00
evgeny 56367d4aef Adapt JOIN scheduler fixture to explicit authenticated routes 2026-10-30 23:42:05 +01:00
evgeny 616ca3ba99 Exercise authenticated BLE JOIN against tampering and replay 2026-10-30 23:41:18 +01:00
evgeny a5d7833e16 Test invitation bootstrap without IP and independent INVITE frame limits 2026-10-30 23:40:56 +01:00
evgeny e88de767ac Release pending bootstrap routes on channel deletion and expiry 2026-10-30 23:40:21 +01:00
evgeny 8dfb9d373f Close cancelled bootstrap sessions and permit fresh bounded retries 2026-10-30 23:37:34 +01:00
evgeny ad8e05c823 Build BLE join carrier in Android native client 2026-10-30 23:36:19 +01:00
evgeny 38c1287b45 Connect BLE bootstrap lifecycle to the shared chat JOIN carrier 2026-10-30 23:36:19 +01:00
evgeny a290234f8a Implement bounded authenticated JOIN transport over BLE INVITE 2026-10-30 23:35:28 +01:00
evgeny 135bfe8132 Bound large INVITE frames separately from BLE DATA 2026-10-30 23:34:04 +01:00
evgeny 6344ff2ecb Share JOIN state machine across ETCP and authenticated carriers 2026-10-30 23:33:57 +01:00
evgeny 8a0cc6f5e1 Add scoped authenticated carrier interface for chat joins 2026-10-30 23:32:47 +01:00
evgeny 44c796a72f Define authenticated BLE join bootstrap architecture 2026-10-30 23:32:26 +01:00
evgeny f40f2cba71 Record BLE join bootstrap deadlock after delivered invitation 2026-10-30 23:23:31 +01:00
evgeny a50af06639 Record BLE invitation diagnosis and remaining initial ACL timeout 2026-10-30 23:19:53 +01:00
evgeny ce89fd1e2c Clarify BLE delivery failures and document connection reuse 2026-10-30 23:18:25 +01:00
evgeny 920ea7ae2c Report failed BLE invitation delivery without success wording 2026-10-30 23:18:13 +01:00
evgeny 13094ae7d6 Reuse connected BlueZ GATT before requesting another bearer 2026-10-30 23:16:15 +01:00
evgeny eafa1297dd Fix WinRT test operation interface conversion 2026-10-30 23:06:55 +01:00
evgeny ca2bebcbd3 Document incoming BLE tuning and refine cancellation test 2026-10-30 23:05:52 +01:00
evgeny 2902602d7f Tune incoming Windows BLE connections for throughput 2026-10-30 23:05:36 +01:00
evgeny 3b9f503ef3 Record completed link admission checks and the separate invitation listener issue 2026-10-30 22:53:57 +01:00
evgeny 89829ca9b6 Describe admission policy as a property of the Bluetooth link 2026-10-30 22:50:45 +01:00
evgeny eda5d99530 Test link-local rejection and unrestricted sockets on shared connections 2026-10-30 22:50:23 +01:00
evgeny 16b1003710 Finish removing connection-level policy arguments 2026-10-30 22:50:12 +01:00
evgeny 5eb0701a41 Keep connection construction independent from link admission policy 2026-10-30 22:50:12 +01:00
evgeny 8d6aef37da Keep connection construction independent from link admission policy 2026-10-30 22:50:11 +01:00
evgeny 510dbc2e15 Keep connection construction independent from link admission policy 2026-10-30 22:50:11 +01:00
evgeny e09a3f9052 Keep connection construction independent from link admission policy 2026-10-30 22:50:11 +01:00
evgeny 2c1ba2b1c0 Keep connection construction independent from link admission policy 2026-10-30 22:50:10 +01:00
evgeny a5299749fb Keep connection construction independent from link admission policy 2026-10-30 22:50:10 +01:00
evgeny dcc7e2f8d7 Make authenticated known-key admission strictly local to each link 2026-10-30 22:49:59 +01:00
evgeny fd05e13525 Remove peer admission policy from shared ETCP connections 2026-10-30 22:49:59 +01:00
evgeny 847fedeac7 Verify encrypted UTUN socket handshakes on BLE-origin shared connections 2026-10-30 22:47:39 +01:00
evgeny 9e01b910ce Document socket policy isolation and prepare native handshake regression 2026-10-30 22:47:14 +01:00
evgeny 80e85bbec6 Keep UTUN socket admission independent from shared BLE connection defaults 2026-10-30 22:46:46 +01:00
evgeny 20e0f6581a Reject restricted paths on existing connections without closing other transports 2026-10-30 22:43:35 +01:00
evgeny 6a7940450e Clarify constructor admission requirements and keep helper below includes 2026-10-30 22:42:50 +01:00
evgeny 6d9ef7383c Recheck peer admission during session handshake and document BLE policy 2026-10-30 22:42:02 +01:00
evgeny 8d92144a5a Test known-key admission, revoked members and unknown invitation-only peers 2026-10-30 22:41:13 +01:00
evgeny ed98ce169e Apply known-peer policy to desktop BLE while keeping explicit hardware probes 2026-10-30 22:40:16 +01:00
evgeny 612b263891 Keep unknown BLE keys in invitation-only mode before ETCP admission 2026-10-30 22:39:59 +01:00
evgeny 3af6ff4961 Specify explicit admission policy in existing ETCP constructors 2026-10-30 22:39:38 +01:00
evgeny 78613d62b5 Specify explicit admission policy in existing ETCP constructors 2026-10-30 22:39:38 +01:00
evgeny 0ff1dc4f66 Specify explicit admission policy in existing ETCP constructors 2026-10-30 22:39:37 +01:00
evgeny 091a1dc053 Specify explicit admission policy in existing ETCP constructors 2026-10-30 22:39:37 +01:00
evgeny 113949083b Specify explicit admission policy in existing ETCP constructors 2026-10-30 22:39:37 +01:00
evgeny 42bb813ee5 Specify explicit admission policy in existing ETCP constructors 2026-10-30 22:39:37 +01:00
evgeny 0850a52180 Check known peer keys after authenticated transport handshake before UP 2026-10-30 22:39:09 +01:00
evgeny 90f70f2b72 Preserve per-link admission policy for shared ETCP connections 2026-10-30 22:38:52 +01:00
evgeny afa834a02d Require known peer admission as an ETCP connection creation policy 2026-10-30 22:38:51 +01:00
evgeny 14e61c68ce Keep known-peer admission policy in the topology module 2026-10-30 22:38:36 +01:00
evgeny 2d054591d5 Validate peer keys against full active group member records 2026-10-30 22:38:36 +01:00
evgeny 8f28adeb0f Record missing BLE incoming group-member admission checks 2026-10-30 22:32:52 +01:00
evgeny 541325c17a Explain BLE advertisement visibility in Android settings 2026-10-30 22:27:51 +01:00
evgeny 55a6abfac5 Explain Bluetooth group connections and unrestricted invitations 2026-10-30 22:26:43 +01:00
evgeny 85be60d716 Enable the three Android BLE connection flags by default 2026-10-30 22:26:43 +01:00
evgeny bb99796140 Verify monitoring enable, disable and endpoint validation contracts 2026-10-30 22:23:15 +01:00
evgeny 168f3e9d97 Add a default-off monitoring switch and conditional endpoint fields 2026-10-30 22:23:15 +01:00
evgeny f6009d3070 Persist optional Android monitoring endpoints into native configuration 2026-10-30 22:23:15 +01:00
evgeny baf58a7971 Record missing Android monitoring configuration wiring 2026-10-30 22:18:42 +01:00
evgeny 6db34b558a Remove the unused Android node listen port preference 2026-10-30 22:18:42 +01:00
evgeny 5bb0df82b6 Clarify Android developer settings labels and warning 2026-10-30 22:18:42 +01:00
evgeny 8f1ede0344 Show the selected Android settings section in the header 2026-10-30 22:12:20 +01:00
evgeny d4a2dac903 Reuse the chat portable radio icon in Android settings 2026-10-30 22:11:55 +01:00
evgeny bd453311ac Use labeled icons for Android settings section tabs 2026-10-30 22:09:05 +01:00
evgeny 9f59e0968e Update call UI checks and document the unified diagnostics window 2026-10-30 21:51:50 +01:00
evgeny b08161b055 Unify call graphs and metrics behind the Diagnostics action 2026-10-30 21:51:32 +01:00
evgeny ad21c49d8f Place call graph canvas alongside a resizable diagnostic text pane 2026-10-30 21:51:10 +01:00
evgeny aa9c3beece Clarify transport summary counters and initial diagnostic baseline 2026-10-30 21:50:11 +01:00
evgeny 2de735f3ff Include route retransmissions and window without creating diagnostic channels 2026-10-30 21:49:15 +01:00
evgeny da1b4839ea Verify diagnostic cadence, filtering and full buffer log delivery 2026-10-30 21:48:43 +01:00
evgeny 97934de381 Test independent log intervals and document diagnostic units 2026-10-30 21:48:17 +01:00
evgeny 5bc6350cc0 Report call route queues and ACK progress at 200ms cadence 2026-10-30 21:47:55 +01:00
evgeny 110b71d17f Share the diagnostic cadence and clamp concurrent pull timestamp skew 2026-10-30 21:47:55 +01:00
evgeny 15d44165da Log audio buffer health every 200ms outside playback locks 2026-10-30 21:47:15 +01:00
evgeny ff992bcd40 Expose bounded audio log snapshots without consuming playback events 2026-10-30 21:46:53 +01:00
evgeny d05aed35f9 Collect exact playback intervals independently from graph history 2026-10-30 21:46:53 +01:00
evgeny 2cd3f966b2 Document fresh CCC preparation and finalize reconnect regression 2026-10-30 21:43:26 +01:00
evgeny 752a3a7d95 Prepare WinRT subscriptions afresh and test BlueZ session replacement 2026-10-30 21:41:38 +01:00
evgeny 68444ef192 Fix BLE subscription reset and incoming session replacement on reconnect 2026-10-30 21:41:13 +01:00
evgeny 88436cde0e Package audio history headers and record outdated call fixtures 2026-10-30 21:31:50 +01:00
evgeny 476ab1b840 Preserve recorded traffic rates as the history window advances 2026-10-30 21:30:52 +01:00
evgeny 8e6efd2b00 Keep graph extrema readable and validate accepted packet counters 2026-10-30 21:27:46 +01:00
evgeny 015e8b75d7 Localize Android audio history graph labels and units 2026-10-30 21:25:11 +01:00
evgeny ca7d64ac2b Add stacked live audio graphs to the Android call screen 2026-10-30 21:25:11 +01:00
evgeny 141148611f Expose shared audio and transmission history to Android 2026-10-30 21:25:11 +01:00
evgeny 355604a862 Document graph measurement boundaries and improve label contrast 2026-10-30 21:23:54 +01:00
evgeny b760cef460 Test audio graph lifecycle, throughput path changes and accepted send accounting 2026-10-30 21:22:12 +01:00
evgeny ef0af0dd5e Localize desktop audio graph labels and measurement units 2026-10-30 21:18:30 +01:00
evgeny 2406ff0f11 Open audio graphs from the desktop call controls 2026-10-30 21:18:19 +01:00
evgeny d1897bd6e6 Add stacked desktop audio history, queue, throughput and histogram plots 2026-10-30 21:18:01 +01:00
evgeny 9d88f63062 Calculate path-aware ETCP throughput over a sliding one second window 2026-10-30 21:15:21 +01:00
evgeny 490515b7c2 Capture call path traffic alongside aggregate transmission queues 2026-10-30 21:14:05 +01:00
evgeny 65f0c62a23 Expose selected Router path traffic counters without borrowing live connections 2026-10-30 21:13:57 +01:00
evgeny 055dd3ada0 Count accepted ETCP wire bytes per connection including control and retries 2026-10-30 21:13:57 +01:00
evgeny 9c8088ac8d Record aggregate Router and transport histories and verify weighted audio statistics 2026-10-30 21:12:20 +01:00
evgeny 1f974e8244 Expose shared call history snapshots to frontends and queue sampling 2026-10-30 21:11:51 +01:00
evgeny 1b566ddbe5 Collect call audio buffer history independently of visible diagnostics 2026-10-30 21:11:18 +01:00
evgeny 09199cc46b Add bounded shared audio history and time weighted histogram snapshots 2026-10-30 21:11:05 +01:00
evgeny e43f95ea83 Keep startup defaults and reset reserve snapshots consistent 2026-10-30 20:05:23 +01:00
evgeny a7bb72a0b7 Replenish playout reserve smoothly and account for packet cadence in delay control 2026-10-30 20:03:49 +01:00
evgeny 0c20766cfe Gate startup on published PCM and test recovery beyond the initial reserve 2026-10-30 19:57:25 +01:00
evgeny b092e09b43 Adapt call batching to queue pressure and verify protected audio startup 2026-10-30 19:54:58 +01:00
evgeny 1960377e5c Prime desktop speech PCM before enabling device consumption 2026-10-30 19:52:56 +01:00
evgeny a3a54af0fe Define protected call startup reserve and explicit queued renderer readiness 2026-10-30 19:52:40 +01:00
evgeny dff64e2871 Account for the completed audio batch in the video barrier fixture 2026-10-30 19:31:29 +01:00
evgeny efd80949cd Document adaptive full batches and Router readiness ownership 2026-10-30 19:30:12 +01:00
evgeny 215f744bbe Verify adaptive batch targets and reject partial sends on a free transport 2026-10-30 19:29:06 +01:00
evgeny 6ae080d417 Require the adaptive frame count before requesting or using a Router slot 2026-10-30 19:28:22 +01:00
evgeny ee5c258b3c Preserve adaptive audio batch target without partial-packet deadlines 2026-10-30 19:28:21 +01:00
evgeny e598568652 Trigger actual lower queue drain in producer readiness test 2026-10-30 19:26:24 +01:00
evgeny ffa1208cb6 Make producer window test independent of min-RTT probing 2026-10-30 19:25:11 +01:00
evgeny 20b3116e7c Cover lazy Router producers and audio batching under backpressure 2026-10-30 19:24:24 +01:00
evgeny 74eb935589 Remove obsolete audio batch delay controller 2026-10-30 19:21:46 +01:00
evgeny e3764991d4 Build call audio batches only when Router grants a send slot 2026-10-30 19:21:29 +01:00
evgeny 273eabbc6e Add cancellable Router send requests at transport readiness 2026-10-30 19:20:17 +01:00
evgeny 2d4b2f10a6 Keep BLE candidate monitoring separate from IP probes 2026-10-30 19:15:17 +01:00
evgeny ca04b098f8 Keep all call streams alive during router recovery and verify RTT ambiguity handling 2026-10-30 18:53:53 +01:00
evgeny 34cbdc3cde Test conservative router recovery and recover lost receive-resume acknowledgements 2026-10-30 18:52:25 +01:00
evgeny 8f5882081f Separate router DATA recovery timers and add adaptive retransmission backoff 2026-10-30 18:49:47 +01:00
evgeny d1886be6f4 Request maximum BLE advertising power and display radio power status 2026-10-30 18:15:37 +01:00
evgeny 8a02704f8b Document BLE startup sequencing and honor publication deadline 2026-10-30 17:55:26 +01:00
evgeny e81fe7030a Cover initial BLE publication and preserve radio diagnostics 2026-10-30 17:54:14 +01:00
evgeny 77979c4058 Start Windows BLE publisher before GATT and sequence updates 2026-10-30 17:52:42 +01:00
evgeny 4eefe43053 Pass desktop BLE identity to transport before startup 2026-10-30 17:50:32 +01:00
evgeny df23626c47 Remove system stall investigation from task list 2026-10-30 17:39:09 +01:00
evgeny 3eb9c46985 Add configurable Opus burst batches for radio transmission 2026-10-30 17:38:43 +01:00
evgeny 049c8ef155 Improve BLE call batching, startup buffering and diagnostics 2026-10-30 16:44:52 +01:00
evgeny 0afccfb624 Probe Windows BLE publisher startup before GATT advertising 2026-10-30 12:55:11 +01:00
evgeny 77edf2bcf7 Show BLE receive counts below Android device nicknames 2026-10-30 12:48:18 +01:00
evgeny 6e53490cdd Add Android text for BLE broadcast receive counts 2026-10-30 12:48:18 +01:00
evgeny 7cd78e9210 Verify BLE neighbor counters without changing invitation fixtures 2026-10-30 12:47:51 +01:00
evgeny 184b02b342 Show per-device BLE receive counts in desktop rows 2026-10-30 12:46:27 +01:00
evgeny 49cbb7e148 Keep BLE counters tied to neighbor table entries 2026-10-30 12:45:56 +01:00
evgeny d86599995c Count received BLE advertisements over each neighbor lifetime 2026-10-30 12:45:18 +01:00
evgeny 0907395779 Document Windows 1809 advertising probe stop acknowledgement 2026-10-30 12:39:42 +01:00
evgeny 8aa4330c72 Handle requested GATT stop in Windows advertising probe 2026-10-30 12:39:17 +01:00
evgeny ace0ce3e85 Test and document Windows BLE radio status diagnostics 2026-10-30 12:18:19 +01:00
evgeny 3e1d1ddbfd Add Windows BLE advertising resource diagnostics 2026-10-30 12:17:19 +01:00
evgeny 4083865c6f Add the legacy BLE example as a reference 2026-10-30 12:12:53 +01:00
evgeny e6c35bc858 Compact Android Bluetooth devices into two-line rows 2026-10-30 12:07:30 +01:00
evgeny 22d8d872c4 Translate Android Bluetooth device list status messages 2026-10-30 11:54:11 +01:00
evgeny 1cbf63e053 Add the Android nearby Bluetooth device list 2026-10-30 11:54:11 +01:00
evgeny 050b2f6d05 Batch Windows installer staging and license queries 2026-10-30 11:44:06 +01:00
evgeny f87f70489a Show Bluetooth addresses in the desktop device list 2026-10-30 11:26:29 +01:00
evgeny eeb2373599 Keep BLE discovery summaries at ten-second intervals 2026-10-30 11:21:04 +01:00
evgeny 2a19c08d62 Report WinRT scan filters and prolonged publisher waiting 2026-10-30 11:11:40 +01:00
evgeny cd62ea0b6e Log BLE discovery decisions and cumulative receive counters 2026-10-30 11:09:54 +01:00
evgeny f7f3636032 Expose precise BLE identity rejection reasons 2026-10-30 11:08:29 +01:00
evgeny 359c6bc843 Reuse PE cache during packaging and test installer completeness 2026-10-30 11:00:08 +01:00
evgeny 0bee366d6b Share cached PE imports and architecture with Windows packaging 2026-10-30 10:59:04 +01:00
evgeny 8617405464 Merge origin/master preserving BLE wire v4 and Windows 1809 support 2026-10-30 10:55:16 +01:00
evgeny 1e6a766347 Cache Windows ChatGUI runtime imports and deployment 2026-10-30 10:52:51 +01:00
evgeny 7d0c394091 Document Windows 1809 BLE cache lookup and diagnostics 2026-10-30 10:31:25 +01:00
evgeny 64770b579d Support WinRT BLE discovery and connection on Windows 1809 2026-10-30 10:30:22 +01:00
evgeny e1e3c9cfde Document unconfirmed BLE acknowledgements and measured latency limits 2026-10-30 04:54:47 +01:00
evgeny 51795a558c Log invalid BLE probe payload and pacing arguments 2026-10-30 04:48:37 +01:00
evgeny 51d2231ac7 Keep BLE probe packet cadence on absolute deadlines 2026-10-30 04:42:24 +01:00
evgeny fc020f4f05 Measure BLE ETCP echo latency with paced small packets 2026-10-30 04:39:05 +01:00
evgeny 09e045a45d Use unconfirmed BLE ACK writes and notifications on Android 2026-10-30 04:39:05 +01:00
evgeny 452ab50f9e Switch WinRT ACK delivery and advertise BLE wire version four 2026-10-30 04:35:42 +01:00
evgeny d0df49446c Send BlueZ flow acknowledgements without ATT responses 2026-10-30 04:35:12 +01:00
evgeny e0076d5d10 Repeat cumulative BLE acknowledgements after unreliable delivery 2026-10-30 04:34:54 +01:00
evgeny 008bafc18a Cover lost cumulative BLE acknowledgements with full duplex windows 2026-10-30 04:34:10 +01:00
evgeny f4bcc6eae9 Log BLE packet sequences and acknowledgements in debug category 2026-10-30 04:31:55 +01:00
evgeny 97b18caa1f Revert "Log the exact reason and lifetime of rejected call invites"
This reverts commit 55637c296f80f016f0a29f54aaa7aaf742b92443.
2026-10-30 04:31:55 +01:00
evgeny 6a2e552194 Log the exact reason and lifetime of rejected call invites 2026-10-30 04:31:55 +01:00
evgeny 93672ae95e Fix desktop BLE mock signature for wire channels 2026-10-29 22:53:35 +01:00
evgeny ae1d149545 Merge branch 'master' of http://git.syqiq.tech/jeka/utun2 2026-10-29 22:43:06 +01:00
evgeny 33a3774938 Require BLE probe publication and document WinRT diagnostics 2026-10-29 22:42:36 +01:00
evgeny dd80f589fa Record successful BLE ACK loads in both connection roles 2026-10-29 22:39:54 +01:00
evgeny 4a7f3253f6 Test WinRT BLE exception isolation and pending shutdown 2026-10-29 22:39:15 +01:00
evgeny dc70174af9 Preserve WinRT BLE event context and diagnose API failures 2026-10-29 22:38:08 +01:00
evgeny 552f7b31b0 Record ACK scheduling regression and successful desktop load 2026-10-29 22:36:14 +01:00
evgeny b1a272fa23 Clarify BLE ACK spacing after local completion 2026-10-29 22:33:17 +01:00
evgeny d5505c054f Reserve the ACK interval after completion for payload traffic 2026-10-29 22:31:17 +01:00
evgeny c52afe4f41 Give DATA a slot between slow cumulative BLE ACKs 2026-10-29 22:29:46 +01:00
evgeny b7e0b1f12c Reproduce DATA starvation behind slow BLE ACK completion 2026-10-29 22:29:32 +01:00
evgeny c83b30aa0b Document BLE v3 ACK framing and bounded remote credit 2026-10-29 22:26:34 +01:00
evgeny 6338a2aae1 Open both fake GATT endpoints before delivering HELLO 2026-10-29 22:22:35 +01:00
evgeny 358c3093dd Refresh WinRT subscriptions before the first incoming value 2026-10-29 22:21:51 +01:00
evgeny fabf0c1663 Reject BLE values before all mandatory subscriptions 2026-10-29 22:21:12 +01:00
evgeny 4016e6b73c Include BLE credit events in the existing wire trace 2026-10-29 22:19:43 +01:00
evgeny c43726c17d Verify BLE ACK timeout independently of local completion 2026-10-29 22:17:57 +01:00
evgeny b31b772e66 Delay remote ACK delivery independently in the BLE fixture 2026-10-29 22:16:46 +01:00
evgeny 46f2137f06 Keep BLE fault injection correct with prefixed fragments 2026-10-29 22:16:08 +01:00
evgeny d33b67d87c Test BLE remote credit, ACK timing, duplex and ID wrap 2026-10-29 22:15:32 +01:00
evgeny 85977d97e0 Verify mandatory ACK subscriptions and addressed BlueZ ACKs 2026-10-29 22:13:46 +01:00
evgeny d4182c22cd Connect the ACK characteristic to Android GATT and JNI 2026-10-29 22:13:46 +01:00
evgeny e7adcbe139 Support the BLE ACK characteristic in WinRT 2026-10-29 22:11:46 +01:00
evgeny dd1769ee4c Adapt BLE identity and ETCP fixtures to the ACK profile 2026-10-29 22:10:40 +01:00
evgeny cecdbbe1d7 Add the mandatory ACK characteristic to BlueZ 2026-10-29 22:10:24 +01:00
evgeny 4e38536a55 Bound BLE DATA flight with cumulative 16-bit ACKs 2026-10-29 22:09:12 +01:00
evgeny be0dff7b2c Define the BLE ACK wire channel and fixed flight budget 2026-10-29 22:08:29 +01:00
evgeny e194535b25 Record RTO validation and remaining BLE throughput work 2026-10-29 21:39:31 +01:00
evgeny 635e1726e6 Document BLE readiness fixes and remaining HCI queue delay 2026-10-29 21:37:40 +01:00
evgeny 55bb052406 Model accepted sends in the ETCP lifecycle fixture 2026-10-29 21:34:02 +01:00
evgeny 0f2794cd51 Format the RTT growth regression cases consistently 2026-10-29 21:25:46 +01:00
evgeny a9bec81328 Let ETCP retransmission timeouts cover measured RTT above one second 2026-10-29 21:18:52 +01:00
evgeny 5b2e11337c Use the native BLE discovery version in Android scan filters 2026-10-29 20:47:48 +01:00
evgeny 285a242d2a Version BLE discovery for unacknowledged DATA compatibility 2026-10-29 20:39:20 +01:00
evgeny b5fb6b0f4d Ignore cached BlueZ advertisements when discovering live BLE peers 2026-10-29 20:29:55 +01:00
evgeny 8081f94ebe Record BLE negotiation evidence and retry pre-transfer radio connections 2026-10-29 20:29:09 +01:00
evgeny 05d78c9960 Add a controlled Android scan pause to the manual BLE probe 2026-10-29 20:14:51 +01:00
evgeny 8ab25c1389 Request high BLE priority for incoming Android links on the shared ACL 2026-10-29 19:58:40 +01:00
evgeny 7dab663b93 Preserve incoming disconnect handling and exercise resolved-service notification 2026-10-29 19:50:44 +01:00
evgeny 51621e6240 Wait for resolved BlueZ services before opening cached GATT characteristics 2026-10-29 19:45:27 +01:00
evgeny 083495986e Document HCI queue delays and explain incompatible GATT properties 2026-10-29 19:10:13 +01:00
evgeny b5b522b732 Log ETCP control submission failures and WinRT error codes 2026-10-29 19:00:53 +01:00
evgeny c5711b5974 Preserve Android BLE failure status and callback diagnostics 2026-10-29 19:00:11 +01:00
evgeny de6e2ada0c Report BLE frame gaps and preserve BlueZ I/O errors 2026-10-29 18:56:50 +01:00
evgeny 8811276ca8 Trace BLE frame delivery and authenticated packet dispatch 2026-10-29 18:46:00 +01:00
evgeny 33b4f0acc8 Record BLE throughput results and harden the hardware probe 2026-10-29 18:38:11 +01:00
evgeny 3def3f5af2 Use unacknowledged BLE DATA and request faster connections 2026-10-29 18:28:05 +01:00
evgeny 9382abb6e6 Fix Windows system library dependencies for uasync 2026-10-29 17:46:18 +01:00
evgeny 5152b17114 Fix BLE link display and remove obsolete tool projects 2026-10-29 17:10:39 +01:00
evgeny f84622966e Add BLE ETCP links and GATT invitations for desktop and Android
Attach packet drivers to initially empty ETCP connections. Share BLE neighbor
tracking and group fallback between desktop and Android in cgathui_common.

Deliver join links through a dedicated Write/Indicate characteristic with
independent fragmentation queues, application acknowledgements, deduplication
and bounded retries. Merge LAN/BLE discovery and add a separate Bluetooth
invitation reception setting to both clients.

Validation: 230 core tests, BLE transport/BlueZ/UI tests, ASAN/UBSAN,
Linux GUI and Android builds, and Windows backend cross-compilation.
Physical Android/Linux invitation exchange passed with either GATT initiator.
The Android-initiated run also verified all 32 ETCP packets of 1500 bytes;
the desktop-initiated load run reached 7/32 within its 45-second time limit.
2026-10-29 16:41:04 +01:00
evgeny ef6a5673bd Preserve member connection state when its refresh fails 2026-10-29 14:02:25 +01:00
evgeny 05ea602a3a Distinguish failed member-link snapshots from confirmed disconnection 2026-10-29 14:02:25 +01:00
evgeny a4c7899ffb Keep native member query failures distinct from valid empty snapshots 2026-10-29 14:02:25 +01:00
evgeny 0878947e13 Describe Android view-model snapshots and application-owned configuration 2026-10-29 14:00:16 +01:00
evgeny 2460e810d6 Document asynchronous BLE detach and report probe cleanup failures 2026-10-29 13:59:14 +01:00
evgeny 0f03aa8b5c Align Android architecture with serialized lifecycle and Bluetooth ownership 2026-10-29 13:56:57 +01:00
evgeny f1f113a5f2 Describe readiness recovery when a rejected restart retains the core 2026-10-29 13:56:57 +01:00
evgeny 0800fd61a7 Retry failed BLE SDK releases and propagate radio command rejection 2026-10-29 13:54:52 +01:00
evgeny 5410c4c6c6 Retain BLE cleanup ownership until each Android release succeeds 2026-10-29 13:53:22 +01:00
evgeny 6c7f5b7032 Apply Bluetooth flag changes atomically without replacing concurrent selections 2026-10-29 13:53:22 +01:00
evgeny 8dc10bb54f Keep Bluetooth settings writes alive and contain Android launch failures 2026-10-29 13:51:59 +01:00
evgeny ae4f524448 Observe confirmed Bluetooth preferences from the application owner 2026-10-29 13:51:58 +01:00
evgeny 1651d1b870 Document native ownership and reject media creation during core cleanup 2026-10-29 13:50:21 +01:00
evgeny 4a5a8cf057 Keep malformed events and deleted database state out of Android UI 2026-10-29 13:49:57 +01:00
evgeny c5879042fb Validate complete channel event frames before publishing state 2026-10-29 13:49:00 +01:00
evgeny d636a03928 Test restart readiness recovery and explicit UTF-8 database cleanup 2026-10-29 13:39:58 +01:00
evgeny 132e222415 Resume retained core owners and observe unexpected service loss 2026-10-29 13:35:42 +01:00
evgeny 791ff42547 Keep database reset atomic and owned beyond the activity lifecycle 2026-10-29 13:35:42 +01:00
evgeny 665137314a Serialize native lifecycle mutations and renew readiness across restart 2026-10-29 13:35:42 +01:00
evgeny 0568d263e0 Reject fresh radio and publisher owners during core cleanup 2026-10-29 13:35:42 +01:00
evgeny 044ff034a6 Await radio and shared audio release before native core teardown 2026-10-29 13:35:42 +01:00
evgeny ea67b491f9 Show private conversation start failures and test stale confirmation isolation 2026-10-29 13:35:41 +01:00
evgeny 321a2c3ed7 Match private conversation confirmations before opening the requested peer 2026-10-29 13:35:41 +01:00
evgeny 69ae8b57cb Bind private conversation start requests to the worker conversation ID 2026-10-29 13:35:41 +01:00
evgeny c1ad35e152 Persist channel mute consistently and own panel preference changes 2026-10-29 13:35:41 +01:00
evgeny fb696d0d56 Report rejected core actions and log nickname write outcomes 2026-10-29 13:35:41 +01:00
evgeny 3aecc095ff Return queue rejection for invite and private conversation requests 2026-10-29 13:35:41 +01:00
evgeny da540627fc Keep accepted commands bound to their instance while restart readiness closes 2026-10-29 13:35:41 +01:00
evgeny f15ca995b7 Close frontend readiness while a restart is pending and retain failed core state 2026-10-29 13:35:41 +01:00
evgeny f50310afed Verify config callback thread attachment and reject truncated database paths 2026-10-29 13:35:41 +01:00
evgeny 20f506fc3c Contain JNI config failures and validate audio result buffers 2026-10-29 13:35:41 +01:00
evgeny af776deed6 Keep member snapshots atomic and verify escaped socket names 2026-10-29 13:35:41 +01:00
evgeny 89a4630477 Build complete network JSON snapshots and verify SQL failure recovery 2026-10-29 13:35:41 +01:00
evgeny 05ab3b8054 Return complete channel snapshots and distinguish database errors from empty history 2026-10-29 13:35:41 +01:00
evgeny 57227b331d Exercise event callback replacement and exceptions on a real JVM 2026-10-29 13:35:41 +01:00
evgeny 2f4cded218 Preserve event callback lifetime and contain JNI delivery exceptions 2026-10-29 13:35:41 +01:00
evgeny 17f79b16cd Run checked JVM string tests with the Android verification tasks 2026-10-29 13:35:41 +01:00
evgeny c0a4beeec4 Verify JNI UTF-8 strings against a real JVM with checked JNI 2026-10-29 13:35:41 +01:00
evgeny 86f0ac7625 Route remaining JNI producers through the core task owner 2026-10-29 13:35:41 +01:00
evgeny 95f0e89567 Read JNI database and live network snapshots in the core worker 2026-10-29 13:35:41 +01:00
evgeny 8614ba5428 Use ordinary UTF-8 across JNI strings and test cancelled media ownership 2026-10-29 13:35:41 +01:00
evgeny 72ee8f2586 Release detached voice and PM file payloads when queued work is cancelled 2026-10-29 13:35:41 +01:00
evgeny 57bfadb04c Retain media request ownership until execution or worker cancellation 2026-10-29 13:35:41 +01:00
evgeny 38ab885609 Expose attachment cancellation as a typed task discard callback 2026-10-29 13:35:41 +01:00
evgeny f731ac340d Serialize bridge command publication and report rejected lifecycle requests 2026-10-29 13:35:41 +01:00
evgeny 8374c60b0e Publish message requests through the worker lifetime owner 2026-10-29 13:35:41 +01:00
evgeny 5a4ddca190 Protect lifecycle producers and leave fatal signals to the platform 2026-10-29 13:35:41 +01:00
evgeny 929df3b6cb Exercise worker request cancellation against real lifecycle teardown 2026-10-29 13:35:41 +01:00
evgeny 8c0c17270e Own frontend tasks through worker teardown and marshal synchronous reads 2026-10-29 13:35:41 +01:00
evgeny d20e112933 Isolate activity cleanup and document startup event ownership 2026-10-29 13:35:41 +01:00
evgeny b8ccd515dd Load startup preferences asynchronously and contain service launch errors 2026-10-29 13:35:41 +01:00
evgeny 013ff93406 Load audio and network settings on IO and document persistent change ownership 2026-10-29 13:35:41 +01:00
evgeny 30648086b4 Contain remaining settings loader failures and remove retired UI scopes 2026-10-29 13:35:41 +01:00
evgeny 828b36f290 Keep failed settings teardown retryable and preserve UI until database stop succeeds 2026-10-29 13:35:41 +01:00
evgeny c5c4d0e588 Load confirmed settings after pending changes and guard invalid audio preferences 2026-10-29 13:35:41 +01:00
evgeny 48564e8ab3 Respect microphone permission callback ownership and test settings disposal 2026-10-29 13:35:19 +01:00
evgeny b086750cf3 Persist audio settings before runtime updates and release hidden microphone tests 2026-10-29 13:35:19 +01:00
evgeny eb837206c3 Own radio settings changes and preserve observed state after IO failures 2026-10-29 13:35:19 +01:00
evgeny 61bdf4a6df Retain observed settings through read failures and retry without default resets 2026-10-29 13:35:19 +01:00
evgeny e8aeaaf365 Apply developer settings only after accepted persistence completes 2026-10-29 13:35:19 +01:00
evgeny a9495de90f Keep settings persistence alive after navigation and guard initial preference loading 2026-10-29 13:35:19 +01:00
evgeny 87166db832 Test settings persistence ownership, ordering and failure isolation 2026-10-29 13:35:19 +01:00
evgeny a95245e272 Own ordered settings changes independently of the Compose screen 2026-10-29 13:35:19 +01:00
evgeny 299518e866 Preserve confirmed settings and manual socket choices after failures 2026-10-29 13:35:19 +01:00
evgeny de907c697b Match temporary IPv6 flags using canonical address bytes 2026-10-29 13:35:19 +01:00
evgeny 268e8794ab Document process lifetime voice ownership and core shutdown prerequisites 2026-10-29 13:35:19 +01:00
evgeny d0d63c1d4b Keep voice cleanup independent of caller cancellation and stop playback promptly 2026-10-29 13:35:19 +01:00
evgeny 48a20cda8c Reject new capture while an IO teardown holds its lifecycle lock 2026-10-29 13:35:19 +01:00
evgeny c7356d2a5b Wait for asynchronous voice cleanup acknowledgement in lifecycle regression test 2026-10-29 13:35:19 +01:00
evgeny 5ee87c535b Avoid capture-lock acquisition while rolling back a playback worker launch 2026-10-29 13:35:19 +01:00
evgeny 3f2cc2abb3 Verify call preparation waits for voice cleanup and document process barriers 2026-10-29 13:35:19 +01:00
evgeny 41ea2afaaa Verify explicit native cancellation failure and document independent audio ownership 2026-10-29 13:35:19 +01:00
evgeny a9099a5ea7 Separate playback controls from blocked capture cleanup and gate stopping cores 2026-10-29 13:35:19 +01:00
evgeny b25766ae5a Test retained voice resources, decoder failures and nonblocking disposal 2026-10-29 13:35:19 +01:00
evgeny bb08b20e58 Wait for voice recording and playback release before call signalling 2026-10-29 13:35:19 +01:00
evgeny a85d2cc8c7 Retain voice resources after ViewModel disposal and block premature core teardown 2026-10-29 13:35:19 +01:00
evgeny 85af6f5b87 Deliver app events once and isolate failures in independent consumers 2026-10-29 13:35:19 +01:00
evgeny 6916575380 Contain headless foreground, notification and teardown failures 2026-10-29 13:34:26 +01:00
evgeny d7fb8568b2 Retry core shutdown until pending frontend resources are released 2026-10-29 13:34:26 +01:00
evgeny 1529dfd04b Document camera finalization ownership and isolate late SDK diagnostics 2026-10-29 13:34:26 +01:00
evgeny 8dd8dc96d7 Verify recorded tracks and handle camera permission and SDK cleanup failures 2026-10-29 13:34:26 +01:00
evgeny 9ac6e4a2f4 Compile track inspection and its SDK boundary in video lifecycle tests 2026-10-29 13:34:26 +01:00
evgeny fca68080bc Own recorded video track inspection until extractor release succeeds 2026-10-29 13:34:26 +01:00
evgeny 8a1c77793d Keep camera caches until finalization and contain recording control failures 2026-10-29 13:34:26 +01:00
evgeny 871acd9383 Test camera writer completion, failed close, binding cleanup and cache transfer 2026-10-29 13:34:26 +01:00
evgeny 09386ee392 Retain camera recording and cache ownership until writer completion 2026-10-29 13:34:26 +01:00
evgeny 3ae8d12434 Keep submission IDs unique across ViewModels and document native cache transfer 2026-10-29 13:34:26 +01:00
evgeny ab6a10026e Verify PM voice receipts and document composer and cache ownership 2026-10-29 13:34:26 +01:00
evgeny 3f0c89a6a3 Verify real PM media commit failures, exact receipts and source cleanup 2026-10-29 13:34:26 +01:00
evgeny 6eb865242b Test video submission validation and retriever cleanup acknowledgements 2026-10-29 13:34:26 +01:00
evgeny 3df64b6744 Use voice commit receipts for both conversation types and document ownership 2026-10-29 13:34:26 +01:00
evgeny dad127d770 Wait for committed PM media and retain native ownership of accepted cache files 2026-10-29 13:34:26 +01:00
evgeny 2dbc45e63d Transfer Android ordinary attachment caches to the shared media worker 2026-10-29 13:34:26 +01:00
evgeny ce80fbcd10 Expose committed PM file results through Android JNI 2026-10-29 13:34:26 +01:00
evgeny d6eed3e9c9 Specify receipt policy in native DM media callers 2026-10-29 13:34:26 +01:00
evgeny 31e461dca2 Carry voice PM receipts and document shared media completion semantics 2026-10-29 13:34:26 +01:00
evgeny e943879c50 Carry Android photo and video request IDs through PM preparation 2026-10-29 13:34:26 +01:00
evgeny 4fd5ebf57a Acknowledge PM media submissions after local commit or preparation failure 2026-10-29 13:34:26 +01:00
evgeny dae19c06d7 Preserve composer commit receipts and finish message batches after rotation 2026-10-29 13:34:26 +01:00
evgeny 47e997df15 Own composed message batches and receipts beyond Activity lifetime 2026-10-29 13:34:26 +01:00
evgeny a0c8d5490c Test atomic JSON snapshots, failure diagnostics and subsequent recovery 2026-10-29 13:34:26 +01:00
evgeny 3eb7f8b0e6 Preserve UI snapshots after parse failure and ignore superseded queries 2026-10-29 13:34:26 +01:00
evgeny 7d67213847 Handle unavailable channel snapshots in Android media consumers 2026-10-29 13:34:26 +01:00
evgeny 4fbb825b9b Reject partial Android repository snapshots and distinguish query failures 2026-10-29 13:34:26 +01:00
evgeny e942190b9f Allow call teardown to defer optional pause when reporter owns the output 2026-10-29 13:34:26 +01:00
evgeny 1097c24d91 Document call signalling barriers and isolate routing diagnostic failures 2026-10-29 13:34:26 +01:00
evgeny 5dffdee8ff Document nonblocking audio cleanup and keep lifecycle tests on main 2026-10-29 13:34:25 +01:00
evgeny ff1f7a4bb8 Keep call audio main thread responsive while device workers are blocked 2026-10-29 13:34:25 +01:00
evgeny 314b77242f Test call route persistence and busy outcome failure isolation 2026-10-29 13:34:25 +01:00
evgeny 236dbd3e84 Contain call notification and route persistence failures 2026-10-29 13:34:25 +01:00
evgeny 7e328b3908 Test rejected call signalling and deferred hangup recovery 2026-10-29 13:34:25 +01:00
evgeny 38e2cc4336 Retain failed call end commands until the worker accepts them 2026-10-29 13:34:25 +01:00
evgeny 1600f5710c Return explicit queue results for call signalling commands 2026-10-29 13:34:25 +01:00
evgeny eccf5f451c Use explicit DM test headers and clarify proximity lifecycle text 2026-10-29 13:34:25 +01:00
evgeny f5405cdb3d Verify Android DM commit results and document sensor cleanup retry 2026-10-29 13:34:25 +01:00
evgeny 96166cd3a7 Keep PM drafts until the core confirms persistence 2026-10-29 13:34:25 +01:00
evgeny d5a1e4b962 Request DM persistence acknowledgement and send canonical UTF-8 2026-10-29 13:34:25 +01:00
evgeny c5d8307697 Retain proximity registrations after partial SDK failures 2026-10-29 13:34:25 +01:00
evgeny aa9ca53468 Clarify member update acknowledgement and suppress duplicate downloads 2026-10-29 13:34:25 +01:00
evgeny e0e97f1c7a Guard media previews and cancel interrupted voice recording gestures 2026-10-29 13:34:25 +01:00
evgeny 236aeae828 Bound video thumbnails and share retriever cleanup ownership 2026-10-29 13:34:25 +01:00
evgeny d3e83c3c1a Guard member editor actions and display unsigned node identifiers 2026-10-29 13:34:25 +01:00
evgeny 2c2d4f3d9d Validate restored attachment recipients and document conversation UI 2026-10-29 13:34:25 +01:00
evgeny 98d4f903a0 Report channel file export failures and preserve attachment choices 2026-10-29 13:34:25 +01:00
evgeny 666210c3fb Preserve selected attachment targets and contain composer errors 2026-10-29 13:34:25 +01:00
evgeny 89cf180984 Document local video playback and metadata release contracts 2026-10-29 13:34:25 +01:00
evgeny e18ecda41e Fix video fixture ownership and identify playback resource diagnostics 2026-10-29 13:34:25 +01:00
evgeny 8678ace89b Test local video SDK failures, stale callbacks and release barriers 2026-10-29 13:34:25 +01:00
evgeny 5694f97f12 Add controllable SDK boundaries for local video lifecycle tests 2026-10-29 13:34:25 +01:00
evgeny 7ec46278af Keep video gesture callbacks current and forbid reads during cleanup 2026-10-29 13:34:25 +01:00
evgeny fdecfe1b78 Drive video controls from SDK outcomes and preserve paused playback 2026-10-29 13:34:25 +01:00
evgeny d9661d0f59 Own local video playback resources through confirmed SDK release 2026-10-29 13:34:25 +01:00
evgeny 401edd37b8 Document call view ownership and preserve probe interrupts 2026-10-29 13:34:25 +01:00
evgeny 623344369f Guard call permission results and release video targets idempotently 2026-10-29 13:34:25 +01:00
evgeny c8ecf89424 Handle PM document export failures and stale channel dialogs 2026-10-29 13:34:25 +01:00
evgeny 096c1ee2a8 Report probe worker failures and attempt independent SDK cleanup 2026-10-29 13:34:25 +01:00
evgeny 6f5850b9ca Reject empty codec probe runs and preserve decoder cleanup 2026-10-29 13:34:25 +01:00
evgeny 9383a68f17 Release failed member snapshot requests and validate deletion frames 2026-10-29 13:34:25 +01:00
evgeny 36af8d077f Handle stream capture permission failures and document preview release 2026-10-29 13:34:25 +01:00
evgeny 45d1b50cb4 Release preview UI leases even without texture destroy callbacks 2026-10-29 13:34:25 +01:00
evgeny b3f5c49c4d Keep stream catalogue labels current and preserve viewer errors 2026-10-29 13:34:25 +01:00
evgeny 6f0bc4307f Document QR task ownership and application license assets 2026-10-29 13:34:25 +01:00
evgeny f7a80d0a3a Exercise QR cleanup during pending tasks and SDK failures 2026-10-29 13:34:25 +01:00
evgeny 36328814e6 Compile real QR scanner ownership in video host tests 2026-10-29 13:34:25 +01:00
evgeny 41208833b6 Model asynchronous ML Kit tasks and scanner failures in host tests 2026-10-29 13:34:25 +01:00
evgeny 68997853b2 Add CameraX boundaries for QR resource lifecycle tests 2026-10-29 13:34:25 +01:00
evgeny 857338a386 Retain QR scanner resources through asynchronous task completion 2026-10-29 13:34:25 +01:00
evgeny dc09332b2e Share immersive window restoration across stream viewers 2026-10-29 13:34:25 +01:00
evgeny efe421b162 Restore viewer window state and handle photo decoding errors 2026-10-29 13:34:25 +01:00
evgeny bd4bd47e00 Recover join dialog after clipboard and connection errors 2026-10-29 13:34:25 +01:00
evgeny 87b7c6f36c Clarify setup and invitation dialog contracts 2026-10-29 13:34:25 +01:00
evgeny a4a4707c4a Describe NAT snapshots and stream buffer indicator limits 2026-10-29 13:34:25 +01:00
evgeny a442cea1b2 Handle emoji playback failures and clarify image gesture contracts 2026-10-29 13:34:25 +01:00
evgeny 104d70d465 Handle audio device menu launch errors and document UI ownership 2026-10-29 13:34:25 +01:00
evgeny 257df6c520 Describe publisher navigation and video viewport geometry 2026-10-29 13:34:25 +01:00
evgeny 83ba4a03a6 Clarify call banner and status icon presentation contracts 2026-10-29 13:34:25 +01:00
evgeny a7b3d0fc51 Document Telecom cleanup and confirmed route ownership 2026-10-29 13:34:25 +01:00
evgeny eaed746934 Verify radio restoration waits for both service and Telecom release 2026-10-29 13:34:25 +01:00
evgeny e81138e3d1 Await Telecom cleanup before restoring the previous radio session 2026-10-29 13:34:25 +01:00
evgeny 870f1b5914 Clarify Android build modules and handle rejected boot service requests 2026-10-29 13:34:25 +01:00
evgeny 1954c36367 Clarify Telecom ownership and distinguish requested from confirmed cleanup 2026-10-29 13:34:25 +01:00
evgeny 37c72cc2fb Report the retained service ID after the combined teardown check 2026-10-29 13:34:25 +01:00
evgeny 9f1b09aefe Verify Telecom cleanup blocks media and new foreground ownership 2026-10-29 13:34:25 +01:00
evgeny b71f992a45 Retain the media teardown barrier while Telecom cleanup is pending 2026-10-29 13:34:25 +01:00
evgeny e7a03f33fb Cover endpoint callback order and malformed Telecom service requests 2026-10-29 13:34:25 +01:00
evgeny 90e33f568b Validate Telecom request identity and contain extras decoding errors 2026-10-29 13:34:25 +01:00
evgeny 482e1658b0 Preserve the latest route choice while endpoint confirmation is pending 2026-10-29 13:34:25 +01:00
evgeny 8d3cee4a56 Exercise real Telecom ownership, callbacks and endpoint routing 2026-10-29 13:34:25 +01:00
evgeny 8a9e421ea7 Ignore ended Telecom callbacks and contain route listener failures 2026-10-29 13:34:25 +01:00
evgeny f031e510b8 Model Telecom state, endpoint outcomes and ConnectionService requests 2026-10-29 13:34:25 +01:00
evgeny 3babc636b4 Compile real Telecom integration against explicit host boundaries 2026-10-29 13:34:25 +01:00
evgeny 06058fad8e Add URI and main executor boundaries for Telecom host tests 2026-10-29 13:34:25 +01:00
evgeny 7d4a0e05fd Allow explicit Telecom cleanup retry after a rejected timer 2026-10-29 13:34:25 +01:00
evgeny 01a84c6851 Retain retiring Telecom connections and reject duplicate registrations 2026-10-29 13:34:25 +01:00
evgeny c136ff60c2 Document acknowledged publisher shutdown and lifecycle fault coverage 2026-10-29 13:34:25 +01:00
evgeny e5d3a1d584 Cover partial capture startup and callbacks from retired camera owners 2026-10-29 13:34:25 +01:00
evgeny 4af2402e20 Exercise capture ownership across Camera2, Surface, microphone and Opus failures 2026-10-29 13:34:25 +01:00
evgeny 6194538963 Preserve the earliest publisher cleanup retry across repeated shutdowns 2026-10-29 13:34:25 +01:00
evgeny 41a4a2e37e Compile real publisher capture with controlled microphone and native boundaries 2026-10-29 13:34:25 +01:00
evgeny 7a2fc0112c Model capture codec callbacks and Camera2 sessions for host fault tests 2026-10-29 13:34:24 +01:00
evgeny 59d1839d8d Exercise publisher lifecycle failures, retained capture and stale notifications 2026-10-29 13:34:24 +01:00
evgeny f1ffd21cda Report missing publisher system services and use current app language 2026-10-29 13:34:24 +01:00
evgeny 9166268102 Compile publisher service and controller in the lifecycle test harness 2026-10-29 13:34:24 +01:00
evgeny 1beb19a7f8 Expose publisher service boundaries to the existing lifecycle harness 2026-10-29 13:34:24 +01:00
evgeny e49ccfeb64 Guard publisher handshake, error callbacks and native teardown 2026-10-29 13:34:24 +01:00
evgeny 2abdb229fd Keep publisher service owners until capture and foreground cleanup are acknowledged 2026-10-29 13:34:24 +01:00
evgeny 68d21fbffa Acknowledge stream capture shutdown only after every owner is released 2026-10-29 13:34:24 +01:00
evgeny 5e9f7e01e0 Preserve capture camera and session ownership through late callbacks 2026-10-29 13:34:24 +01:00
evgeny fd1e3a7f77 Adopt passive stream capture ownership before starting SDK resources 2026-10-29 13:34:24 +01:00
evgeny 100d208a9a Document stream resource barriers and retained routing registrations 2026-10-29 13:34:24 +01:00
evgeny a1c624a819 Preserve the next KEY after a GAP within one native stream batch 2026-10-29 13:34:24 +01:00
evgeny 0330f30c53 Verify orphan routing listener cleanup and independent route release 2026-10-29 13:34:24 +01:00
evgeny 2516545f9d Retain failed media routing listener removals for acknowledged retry 2026-10-29 13:34:24 +01:00
evgeny ee20c8b9b7 Guard viewer startup and cover the native teardown barrier 2026-10-29 13:34:24 +01:00
evgeny 495d399691 Block native teardown until viewer and shared mixer cleanup is confirmed 2026-10-29 13:34:24 +01:00
evgeny 16c7d817cc Keep mixer shutdown inside the guarded cleanup path 2026-10-29 13:34:24 +01:00
evgeny 304b48a289 Verify stream viewer cleanup barriers with native and SDK faults 2026-10-29 13:34:24 +01:00
evgeny e072624c8d Keep the host audio threshold API compatible with Android signatures 2026-10-29 13:34:24 +01:00
evgeny 68651795bf Compile real stream viewer and mixer for host lifecycle tests 2026-10-29 13:34:24 +01:00
evgeny 5dffa9917f Add controlled native stream and Android audio test boundaries 2026-10-29 13:34:24 +01:00
evgeny 43a749d8ab Use retained Surface leases for stream viewer texture cleanup 2026-10-29 13:34:24 +01:00
evgeny 35fe0ecda1 Exercise stream decoder and audio device failure ownership 2026-10-29 13:34:24 +01:00
evgeny 5b80d5769d Compile the real stream video worker against controlled SDK boundaries 2026-10-29 13:34:24 +01:00
evgeny 26348b35e8 Retain stream audio owners through partial startup and failed release 2026-10-29 13:34:24 +01:00
evgeny f28f95a501 Keep viewer resources and Surface callbacks until cleanup succeeds 2026-10-29 13:34:24 +01:00
evgeny 2f353bf35e Retain stream decoder ownership until worker and SDK cleanup finish 2026-10-29 13:34:24 +01:00
evgeny aa27892c12 Reject regressed stream PTS before submitting it to the decoder 2026-10-29 13:34:24 +01:00
evgeny 5e6313377b Publish verified encoder modes only after successful probe cleanup 2026-10-29 13:34:24 +01:00
evgeny 96f8e6db5b Document acknowledged video shutdown and passive resource adoption 2026-10-29 13:34:24 +01:00
evgeny e9fa7ebb45 Exercise camera teardown despite RX or captured-image cleanup errors 2026-10-29 13:34:24 +01:00
evgeny ea121ac4e7 Model failed-session acknowledgement and verify live preview fallback 2026-10-29 13:34:24 +01:00
evgeny 2068774d58 Clean camera resources independently of RX and image release failures 2026-10-29 13:34:24 +01:00
evgeny e6e3006128 Test Camera2 configuration failure and preview output retention 2026-10-29 13:34:24 +01:00
evgeny 4d559dc08b Handle failed Camera2 sessions without waiting for an absent callback 2026-10-29 13:34:24 +01:00
evgeny 53340db0e3 Verify independent image and codec cleanup under SDK failures 2026-10-29 13:34:24 +01:00
evgeny 43992bb6b3 Expose codec resource ownership to host fault tests 2026-10-29 13:34:24 +01:00
evgeny d9959e5176 Keep codec cleanup diagnostics independent of released SDK handles 2026-10-29 13:34:24 +01:00
evgeny b519536237 Retain codec and input image owners across failed cleanup 2026-10-29 13:34:24 +01:00
evgeny bf3d4f14e8 Keep pending video cleanup distinct from service shutdown failure 2026-10-29 13:34:24 +01:00
evgeny 87e90b9462 Cover late camera callbacks, rejected cleanup and video port recovery 2026-10-29 13:34:24 +01:00
evgeny 776cec590e Retry each pending encoder once per cleanup pass with the shared backoff 2026-10-29 13:34:24 +01:00
evgeny 682ed68d2f Exercise explicit video startup after host tests adopt resource ownership 2026-10-29 13:34:24 +01:00
evgeny 2320aa4f71 Retain the video engine in the call service before starting its workers 2026-10-29 13:34:24 +01:00
evgeny fba07e893f Separate passive video ownership from explicit worker startup 2026-10-29 13:34:24 +01:00
evgeny 5e9dad2e9e Handle camera error callbacks promised alongside synchronous open failures 2026-10-29 13:34:24 +01:00
evgeny a6f41c0256 Confirm camera codec and native video cleanup before acknowledging shutdown 2026-10-29 13:34:24 +01:00
evgeny 53383ec754 Reproduce premature video shutdown acknowledgments and lost camera cleanup owners 2026-10-29 13:34:24 +01:00
evgeny 43f61f6f0b Model pending video shutdown separately from an exception in service tests 2026-10-29 13:34:24 +01:00
evgeny 1ddd2a4a0b Let call service retain video ownership while asynchronous shutdown is pending 2026-10-29 13:34:24 +01:00
evgeny 12db99531f Compile the real call video engine alongside its receive worker in host tests 2026-10-29 13:34:24 +01:00
evgeny 63f393c615 Provide video engine capability, encoder and native port test boundaries 2026-10-29 13:34:24 +01:00
evgeny 3a4e1c6a7c Model Camera2 device session and image reader ownership for lifecycle faults 2026-10-29 13:34:24 +01:00
evgeny 5ad36ba57b Support direct preview buffer sizing and YUV capture format in host fixtures 2026-10-29 13:34:24 +01:00
evgeny 92a301ae54 Provide camera context and fault-controlled orientation sensor boundaries 2026-10-29 13:34:24 +01:00
evgeny 278efd574e Run camera handler tasks on real host worker threads with controlled main timers 2026-10-29 13:34:24 +01:00
evgeny d88d77c14d Specify call snapshot units and the limited config getter interface 2026-10-29 13:34:24 +01:00
evgeny 1596088ca0 Describe camera capability candidates and canonical UDP logger targets 2026-10-29 13:34:24 +01:00
evgeny 8e4d28c1fc Document camera preset restoration, orientation and manual bitrate bounds 2026-10-29 13:34:24 +01:00
evgeny 97f1eaa048 Clarify stream grid and PCM timeline contracts without per-record allocations 2026-10-29 13:34:24 +01:00
evgeny ffa5dece4f Validate stream snapshot counts and verify native metadata mappings 2026-10-29 13:34:24 +01:00
evgeny a1dcf28bf9 Reject malformed stream batches before mutating the playback queue 2026-10-29 13:34:24 +01:00
evgeny 5fb6e72c43 Describe stream source snapshots, codec framing and playback telemetry contracts 2026-10-29 13:34:24 +01:00
evgeny cc7648bb33 Validate length-prefixed NAL headers consistently with Annex B input 2026-10-29 13:34:24 +01:00
evgeny 92ce2d84e9 Describe preview lease transfer, callback cancellation and physical cleanup retries 2026-10-29 13:34:24 +01:00
evgeny 0a777baabb Adopt a fresh preview lease when a previous command lease was cancelled 2026-10-29 13:34:24 +01:00
evgeny 44a137e23b Verify preview ownership, callback rollback and independent physical release retries 2026-10-29 13:34:24 +01:00
evgeny 4d15c6d42a Keep preview cleanup retryable after scheduling rejection and compile real leases in host tests 2026-10-29 13:34:24 +01:00
evgeny 83ea839d0c Recognize shared preview sources and model texture cleanup failures 2026-10-29 13:34:24 +01:00
evgeny 4a40fb9d52 Give preview owners independent leases and retain failed physical cleanup 2026-10-29 13:34:24 +01:00
evgeny 4ba21b3082 Remove the trailing blank line from the audited video JNI declarations 2026-10-29 13:34:24 +01:00
evgeny b2b34df2ec Document video receive cleanup acknowledgments and host fault coverage 2026-10-29 13:34:24 +01:00
evgeny 8040431a4a Specify call video bitrate, cadence and orientation helper contracts 2026-10-29 13:34:24 +01:00
evgeny 98cd5bf81c Describe call video JNI buffers, return values and playout handle ownership 2026-10-29 13:34:24 +01:00
evgeny 000273d451 Keep the earliest pending video cleanup retry instead of postponing it twice 2026-10-29 13:34:24 +01:00
evgeny d8fd73d917 Exercise video RX cleanup failures, surface leases and generation draining 2026-10-29 13:34:24 +01:00
evgeny 71e1e5c747 Run real call video receive tests with controlled native and codec boundaries 2026-10-29 13:34:24 +01:00
evgeny 7f89b7c734 Provide controlled MediaCodec input output and cleanup failures 2026-10-29 13:34:24 +01:00
evgeny 8951af6b63 Model video surfaces and deterministic cleanup retry timers on the JVM 2026-10-29 13:34:24 +01:00
evgeny af2209ec96 Prepare host video tests and initialize receive ownership before starting its worker 2026-10-29 13:34:24 +01:00
evgeny eff6f8965a Retain video receive resources through failed decoder and surface cleanup 2026-10-29 13:34:24 +01:00
evgeny 448fa39a0c Separate call video format values from the native runtime boundary 2026-10-29 13:34:24 +01:00
evgeny 99ab91d2f5 Clarify router cleanup as a native audio teardown prerequisite 2026-10-29 13:34:24 +01:00
evgeny bc6ca78ce8 Document retained router resources and shared session close acknowledgments 2026-10-29 13:34:23 +01:00
evgeny 774dc10d84 Preserve configured Telecom ownership when startup retries router cleanup 2026-10-29 13:34:23 +01:00
evgeny e660f8f762 Cover partial communication selection and SCO cleanup effects 2026-10-29 13:34:23 +01:00
evgeny 8cdb4190b6 Log rejected media operations while session cleanup remains pending 2026-10-29 13:34:23 +01:00
evgeny a6f8156564 Track possible SCO effects before starting the Android request 2026-10-29 13:34:23 +01:00
evgeny 48ab63a9d3 Test router cleanup barriers in call and shared media owners 2026-10-29 13:34:23 +01:00
evgeny b3e1356d16 Exercise retained router cleanup, stale proxies and SCO failure recovery 2026-10-29 13:34:23 +01:00
evgeny 3ef245fc0a Verify pending router cleanup through repeatable stop calls 2026-10-29 13:34:23 +01:00
evgeny f7ebf81061 Ignore repeated Bluetooth callbacks for proxies already released 2026-10-29 13:34:23 +01:00
evgeny 3d2e98b02e Keep media audio session close retryable until router cleanup succeeds 2026-10-29 13:34:23 +01:00
evgeny 1970f895da Retain router resources and retry incomplete audio route cleanup 2026-10-29 13:34:23 +01:00
evgeny 1da06164e2 Document retryable call audio shutdown and device ownership 2026-10-29 13:34:23 +01:00
evgeny 94b5d44fe7 Check call audio main ownership and the late Telecom handoff 2026-10-29 13:34:23 +01:00
evgeny 326bfd124e Guard call audio ownership on main and avoid touching released devices 2026-10-29 13:34:23 +01:00
evgeny 0340a59b15 Dispatch host mainExecutor callbacks through the main looper 2026-10-29 13:34:23 +01:00
evgeny f385d3dc5e Cover call audio teardown and partial device startup failures 2026-10-29 13:34:23 +01:00
evgeny 83a671b72f Compile the real call audio engine in host regression tests 2026-10-29 13:34:23 +01:00
evgeny ecd4e12274 Provide call DSP and Telecom boundaries for real audio worker tests 2026-10-29 13:34:23 +01:00
evgeny 7304647baa Model call audio hardware failures and blocking capture on the JVM 2026-10-29 13:34:23 +01:00
evgeny e857b9de75 Retain call audio owners until worker and device cleanup succeeds 2026-10-29 13:34:23 +01:00
evgeny a1c77268b8 Document retained call service cleanup, retry policy and native core teardown barriers 2026-10-29 13:34:23 +01:00
evgeny 6ac6dd1f6f Describe call teardown acknowledgments and the boundary of asynchronous video cleanup 2026-10-29 13:34:23 +01:00
evgeny 02763bd4a1 Reject missing service components instead of waiting forever for Android startup 2026-10-29 13:34:23 +01:00
evgeny 4dd84c601b Cover null foreground service results in call and overlay startup 2026-10-29 13:34:23 +01:00
evgeny d2c6734bfb Model Android service requests that return no matching component 2026-10-29 13:34:23 +01:00
evgeny 17dc0b26b4 Preserve the service call identity until its final lifecycle notification 2026-10-29 13:34:23 +01:00
evgeny 42c6e2a62b Keep service loss associated with the call after local resources are released 2026-10-29 13:34:23 +01:00
evgeny 9b0ca7ca2b Document call service resource acknowledgments and contain conflict callback errors 2026-10-29 13:34:23 +01:00
evgeny aefca81444 Keep cancelled media preparation inside the native teardown barrier 2026-10-29 13:34:23 +01:00
evgeny ca7b23909b Use retained resource ownership instead of Deferred cancellation as the cleanup barrier 2026-10-29 13:34:23 +01:00
evgeny a5d8131d8d Verify call cleanup completion, core barriers, retry lifetime and stale callbacks 2026-10-29 13:34:23 +01:00
evgeny 3e7ac47d18 Close the independent call service cleanup block at the correct scope 2026-10-29 13:34:23 +01:00
evgeny 826055d08b Keep failed video shutdown joins and rejected cleanup requests retryable 2026-10-29 13:34:23 +01:00
evgeny 878f71e211 Wait for call service cleanup before restoring media and stopping the native core 2026-10-29 13:34:23 +01:00
evgeny cf793ce6bb Confirm call cleanup before releasing ownership and retry every retained resource independently 2026-10-29 13:34:23 +01:00
evgeny 8eb2363177 Retain call service startup owners before IPC effects and isolate callback failures 2026-10-29 13:34:23 +01:00
evgeny 4f9bfbbcf3 Reference the host service lifecycle result through its Android boundary 2026-10-29 13:34:23 +01:00
evgeny ff05e34d22 Compile call integration models and contain missing notification service errors 2026-10-29 13:34:23 +01:00
evgeny 9c70858828 Exercise call service startup, partial IPC effects and independent cleanup failures 2026-10-29 13:34:23 +01:00
evgeny dd9aac79a2 Handle absent notification managers and nullable call channels explicitly 2026-10-29 13:34:23 +01:00
evgeny 15a2a7bb70 Control audio and video cleanup effects around the real call service controller 2026-10-29 13:34:23 +01:00
evgeny be3a2d2325 Add isolated host checks for the real call service and controller 2026-10-29 13:34:23 +01:00
evgeny bc7063966d Expose call signaling and saved route boundaries to service integration tests 2026-10-29 13:34:23 +01:00
evgeny 1600452147 Model call power events and supported foreground API levels 2026-10-29 13:34:23 +01:00
evgeny 68b922bf80 Expose call foreground intents, receivers and service type contracts 2026-10-29 13:34:23 +01:00
evgeny 0a48cccd9a Model ongoing call notifications and independent foreground stop failures 2026-10-29 13:34:23 +01:00
evgeny a65385bbb1 Keep radio outcomes separate from the live stream foreground notification 2026-10-29 13:34:23 +01:00
evgeny a90416f50c Preserve stream notifications and synchronize host checks with audio cleanup 2026-10-29 13:34:23 +01:00
evgeny 0d9dabcd23 Cover touch permission checks with the overlay error boundary 2026-10-29 13:34:23 +01:00
evgeny 4de7d7ec9d Document overlay service handshake, window cleanup and gesture error ownership 2026-10-29 13:34:23 +01:00
evgeny 1559e0681b Verify overlay latch release, drag lock and position ownership contracts 2026-10-29 13:34:23 +01:00
evgeny 5553d968b6 Deliver cancelled service creation and account for self-context stop requests 2026-10-29 13:34:23 +01:00
evgeny abef146325 Stop unused overlay foreground capture after touch and permission failures 2026-10-29 13:34:23 +01:00
evgeny 36368640f1 Exercise overlay PTT through native capture and permission-loss stop races 2026-10-29 13:34:23 +01:00
evgeny 982315bacc Cancel overlay PTT on gesture faults and ignore callbacks from retired windows 2026-10-29 13:34:23 +01:00
evgeny b3d70ea92e Retain overlay windows through partial IPC failures and guarded service startup 2026-10-29 13:34:23 +01:00
evgeny fa14305349 Avoid a host settings getter collision with the application API 2026-10-29 13:34:23 +01:00
evgeny 08f3b892a5 Separate overlay notification ownership and recover rejected service actions 2026-10-29 13:34:23 +01:00
evgeny d6c178a39b Keep host window lookup separate from the service-owned window field 2026-10-29 13:34:23 +01:00
evgeny 18cb661c91 Reproduce overlay partial IPC effects, stale gestures and foreground lifecycle failures 2026-10-29 13:34:23 +01:00
evgeny 2f43407ae4 Require an available notification manager at overlay IPC boundaries 2026-10-29 13:34:23 +01:00
evgeny 19050cd4f2 Use the real overlay service with radio lifecycle components in host tests 2026-10-29 13:34:23 +01:00
evgeny ff16eec78d Expose overlay notification and state resource identifiers to JVM tests 2026-10-29 13:34:23 +01:00
evgeny 263d1348ec Model overlay permissions and persistent settings for service tests 2026-10-29 13:34:23 +01:00
evgeny ce756ed6a9 Expose foreground type and deferred layout contracts in overlay fixtures 2026-10-29 13:34:23 +01:00
evgeny 19fd2d3042 Provide overlay drawing boundaries without Android rendering 2026-10-29 13:34:23 +01:00
evgeny d1dc3bb8f7 Model overlay window IPC and foreground service lifetime for Android host tests 2026-10-29 13:34:23 +01:00
evgeny 6d5b2bd176 Record distinct radio core availability and busy outcomes 2026-10-29 13:34:23 +01:00
evgeny 6ee4aa99eb Report unavailable core accurately and include malformed radio event fields 2026-10-29 13:34:23 +01:00
evgeny 16a9bee8f3 Distinguish unavailable radio signaling from an occupied call slot 2026-10-29 13:34:23 +01:00
evgeny 8100ea728e Document Android radio invitation ownership, UI phases and fault checks 2026-10-29 13:34:23 +01:00
evgeny 6ec8950a85 Clarify asynchronous radio signaling and wire identity contracts 2026-10-29 13:34:23 +01:00
evgeny cda411a57e Document radio invitation state and cover continuation and stale pending events 2026-10-29 13:34:23 +01:00
evgeny 45992a3dd3 Allow the missing-notification-service fault in radio cleanup assertions 2026-10-29 13:34:23 +01:00
evgeny 8a7f732428 Validate radio call identities and preserve terminal activation states 2026-10-29 13:34:23 +01:00
evgeny b24bee7a89 Own pending radio starts and diagnose every signaling queue refusal 2026-10-29 13:34:23 +01:00
evgeny 16f52c0136 Exercise radio call signaling refusals, identity, activation and notification lifetime 2026-10-29 13:34:23 +01:00
evgeny 93b174ecde Keep radio outcome presentation failures inside the controller lifecycle 2026-10-29 13:34:23 +01:00
evgeny 8b982efa05 Compile the real radio call controller in host lifecycle tests 2026-10-29 13:34:23 +01:00
evgeny a5718c4ca9 Model native radio call requests and controller dependencies in host fixtures 2026-10-29 13:34:23 +01:00
evgeny 5823d6f907 Bind capture startup to the generation of its update request 2026-10-29 13:34:23 +01:00
evgeny 7810137eb0 Handle playback cancellation and document complete radio failure recovery 2026-10-29 13:34:23 +01:00
evgeny b1a888ffb6 Distinguish stop-unblocked writes from active playback failures 2026-10-29 13:34:23 +01:00
evgeny a5fea0c503 Preserve replacement PTT requests during obsolete capture rollback 2026-10-29 13:34:23 +01:00
evgeny 17caeb0a9c Cover capture startup failures that overlap a replacement group 2026-10-29 13:34:23 +01:00
evgeny 6677b3abfe Document radio worker ownership and format failure boundaries 2026-10-29 13:34:23 +01:00
evgeny 613ea315b0 Synchronize radio discontinuity regression with the first capture frame 2026-10-29 13:34:23 +01:00
evgeny ed8d208454 Recover radio worker failures on the owning I/O executor 2026-10-29 13:34:23 +01:00
evgeny a04cfe4441 Keep radio capture owned through startup faults and deferred native cleanup 2026-10-29 13:34:23 +01:00
evgeny 1ddd75e134 Isolate complete short-write frames from playback already in flight 2026-10-29 13:34:23 +01:00
evgeny 9baa72759f Reproduce radio worker failures and stale session cleanup races 2026-10-29 13:34:23 +01:00
evgeny 5d74bcd865 Model radio worker I/O faults and partial native capture effects 2026-10-29 13:34:23 +01:00
evgeny 128af68a89 Invalidate radio settings before reconfiguration and log failed attempts 2026-10-29 13:34:23 +01:00
evgeny 67615cc330 Reproduce stale settings acknowledgements after failed radio reconfiguration 2026-10-29 13:34:23 +01:00
evgeny bb8518ab67 Document radio startup completion and independent cleanup contracts 2026-10-29 13:34:23 +01:00
evgeny 2fd8a35230 Verify failed radio restore and trace resource join completion 2026-10-29 13:34:23 +01:00
evgeny b6ec030128 Bind radio screen callbacks to the originating startup generation 2026-10-29 13:34:23 +01:00
evgeny 7084454e84 Verify radio output lease dependencies and interrupted cleanup 2026-10-29 13:34:23 +01:00
evgeny 7699ebfcf6 Own radio acknowledgement timers and close unschedulable background capture 2026-10-29 13:34:23 +01:00
evgeny 0ba189863e Complete radio startup callbacks after failures and reject stale readiness 2026-10-29 13:34:23 +01:00
evgeny e197f72722 Release radio resources independently and retain failed cleanup owners 2026-10-29 13:34:23 +01:00
evgeny 530dd81a71 Isolate old radio cleanup failures between negative control scenarios 2026-10-29 13:34:23 +01:00
evgeny c1fe2a3cd0 Reproduce radio lifecycle cleanup and startup callback failures 2026-10-29 13:34:23 +01:00
evgeny 45bc97c25b Model radio startup and main queue delivery failures 2026-10-29 13:34:23 +01:00
evgeny 982ed0ca7d Model recoverable receiver and radio output lifecycle failures 2026-10-29 13:34:23 +01:00
evgeny 7780922353 Document radio PTT release fallback and native command coverage 2026-10-29 13:34:22 +01:00
evgeny 46edb1beb5 End radio PTT immediately when its release timer is rejected 2026-10-29 13:34:22 +01:00
evgeny 722ca3e6f7 Drain radio callbacks before terminating the host executor 2026-10-29 13:34:22 +01:00
evgeny ef95ff54b9 Reproduce stuck radio PTT and verify native release ordering 2026-10-29 13:34:22 +01:00
evgeny a162cc6eca Compile the real radio engine in Android host tests 2026-10-29 13:34:22 +01:00
evgeny f494c20430 Keep radio overlay and toast boundaries outside host audio logic 2026-10-29 13:34:22 +01:00
evgeny 6df258cf13 Provide microphone permission resources for radio host tests 2026-10-29 13:34:22 +01:00
evgeny 81b9469302 Observe native radio capture and PTT commands in host tests 2026-10-29 13:34:22 +01:00
evgeny 4ff2f56aa8 Provide radio screen state and monotonic nanoseconds to host tests 2026-10-29 13:34:22 +01:00
evgeny 841d4ecdde Model radio screen receiver registration in host tests 2026-10-29 13:34:22 +01:00
evgeny 51611cbf5a Model radio playback without Android audio hardware 2026-10-29 13:34:22 +01:00
evgeny 9d6018cdbb Describe radio manual holds and independent speaker indication 2026-10-29 13:34:22 +01:00
evgeny 95894273f1 Document radio PTT ownership and talk event state contracts 2026-10-29 13:34:22 +01:00
evgeny 43b14ece78 Unify UDP and STCP packet link API with bounded backpressure 2026-10-29 12:53:57 +01:00
evgeny 3203947698 Add desktop log rotation on startup and size limit 2026-10-29 11:23:36 +01:00
evgeny ba1c4cf160 Add cross-platform BLE transport and Bluetooth settings
Integrate shared C transport with desktop and Android frontends, add radio probes and detailed Windows diagnostics, and fix GUI build dependencies and early configuration startup errors.
2026-10-29 10:51:19 +01:00
evgeny 221f58c9d2 Draw storage avatars as clear cylinders with curved bands 2026-10-28 17:58:40 +01:00
evgeny 54fdd167c2 Use server and storage role icons instead of member avatars 2026-10-28 17:49:24 +01:00
evgeny c96a63091c Replace supernode lightning with a server icon renderer 2026-10-28 17:48:54 +01:00
evgeny 2b05140e74 Verify actual route labels and local to peer NAT pairs in member details 2026-10-28 17:21:37 +01:00
evgeny faa75a7e1d Show actual member routes and both endpoints' NAT types in desktop details 2026-10-28 17:20:46 +01:00
evgeny 26edd84bb9 Enable MJPEG thumbnail encoding and refresh bundled FFmpeg during Windows builds 2026-10-28 15:56:18 +01:00
evgeny 19cece789e Remove local test databases from version control and ignore their directories 2026-10-28 15:38:52 +01:00
evgeny 9cabb698e2 Exercise cached media preparation in real history widgets across scrolling and reopening 2026-10-28 15:09:35 +01:00
evgeny ba44c31f42 Add focused cache and prepared media rendering checks to desktop tests 2026-10-28 15:06:43 +01:00
evgeny ed19adc1ba Cover persistent preview reuse, PNG alpha, first video frame, rotation and creation based expiry 2026-10-28 15:06:06 +01:00
evgeny 806632b67d Link the persistent preview cache and keep image preparation free of temporary files 2026-10-28 15:04:03 +01:00
evgeny 73b1fc7080 Render cached image and video previews without filesystem access or scaled pixmap allocation 2026-10-28 15:02:28 +01:00
evgeny 60d2ba0fac Prepare visible image and video previews through the shared background cache 2026-10-28 15:01:29 +01:00
evgeny 468af7abbe Add persistent media preview cache with fixed creation timestamps and seven day expiry 2026-10-28 14:57:54 +01:00
evgeny fc5ad51ec3 Clarify ringing phase precedes accepting the call 2026-10-28 14:43:27 +01:00
evgeny 6a82192b02 Document ringback and notification playback ownership contracts 2026-10-28 14:43:27 +01:00
evgeny 776345997f Keep notification players strongly owned throughout playback 2026-10-28 14:43:27 +01:00
evgeny b318627022 Require confirmed media release in existing alert lifecycle tests 2026-10-28 14:43:27 +01:00
evgeny 0b10a38f41 Retain failed media releases and retry without replacing ringback owners 2026-10-28 14:43:27 +01:00
evgeny 383da15d95 Allow absent callbacks after partial ringback listener setup 2026-10-28 14:43:27 +01:00
evgeny 2a4ccd8ca8 Reproduce lost ringback and notification players after release failures 2026-10-28 14:43:27 +01:00
evgeny 512a87502b Document ringtone resource ownership and cleanup retry contracts 2026-10-28 14:43:27 +01:00
evgeny 27b99435c0 Clarify alert stop diagnostics when sound cleanup remains pending 2026-10-28 14:43:27 +01:00
evgeny e45ddd2a7f Require confirmed cleanup in existing ringtone lifecycle tests 2026-10-28 14:43:27 +01:00
evgeny 94b9786d91 Retain ringtone resources and retry cleanup before replacement 2026-10-28 14:43:27 +01:00
evgeny 6abedd8177 Reproduce lost ringtone and focus owners after cleanup failures 2026-10-28 14:43:27 +01:00
evgeny cc9e4f4d85 Model rejected vibration scheduling and partial cancellation 2026-10-28 14:43:27 +01:00
evgeny 7ed1a63b36 Model recoverable alert playback and focus cleanup failures 2026-10-28 14:43:27 +01:00
evgeny edc6b32fa7 Cover orphan notification cleanup through language refresh 2026-10-28 14:43:27 +01:00
evgeny d67991d08a Avoid repeated alert cancellation after successful lifecycle cleanup 2026-10-28 14:43:27 +01:00
evgeny 61e013e762 Check lifecycle refresh does not repeat completed alert cleanup 2026-10-28 14:43:27 +01:00
evgeny 774284b699 Verify repeated cleanup across incoming alert lifecycle failures 2026-10-28 14:43:27 +01:00
evgeny 66e99066f9 Retain incoming alert resources until cleanup succeeds 2026-10-28 14:43:27 +01:00
evgeny 793c2b251b Reproduce lost incoming alert resources after cleanup exceptions 2026-10-28 14:43:27 +01:00
evgeny f4cfe5ba30 Model partial wake lock and notification cleanup failures 2026-10-28 14:43:27 +01:00
evgeny 3a6ef25ca6 Document requested locales and notification language refresh contracts 2026-10-28 14:43:27 +01:00
evgeny 7b8e0a95bb Document language host tests and their runtime boundaries 2026-10-28 14:43:27 +01:00
evgeny 3dfedc8822 Read back locale requests after partial framework failures 2026-10-28 14:43:27 +01:00
evgeny a541484df1 Expose language read and selection failures in the settings UI 2026-10-28 14:43:27 +01:00
evgeny caccb4e56f Add localized language selection and catalog error messages 2026-10-28 14:43:27 +01:00
evgeny 8537ac1e6d Include language lifecycle coverage in Android unit test runs 2026-10-28 14:43:27 +01:00
evgeny 4bffffb0ad Keep language tests compatible with an expanded XML catalog 2026-10-28 14:43:27 +01:00
evgeny 6133257c24 Validate language catalogs and framework failure contracts on the host 2026-10-28 14:43:27 +01:00
evgeny 8720cee7af Keep the headless service fixture separate from Android sources 2026-10-28 14:43:27 +01:00
evgeny fd183a43fe Retry notification language refreshes on every configuration signal 2026-10-28 14:43:27 +01:00
evgeny 5360ee9ff1 Reproduce skipped notification language retries and callback failures 2026-10-28 14:43:27 +01:00
evgeny 9369429600 Observe independent notification refresh attempts in language tests 2026-10-28 14:43:27 +01:00
evgeny 909761b0c5 Provide application and main thread boundaries for language tests 2026-10-28 14:43:27 +01:00
evgeny 638a2a2d6b Model locale resources and AppCompat failures for language tests 2026-10-28 14:43:27 +01:00
evgeny aae145b82a Prepare isolated host tests for application language behavior 2026-10-28 14:43:27 +01:00
evgeny 5e0ed8b077 Document battery exemption query and settings request contracts 2026-10-28 14:43:27 +01:00
evgeny 8551234cfb Show unknown battery exemption state with an explicit retry action 2026-10-28 14:43:27 +01:00
evgeny 0b31f27177 Preserve unknown battery exemption status on Android service errors 2026-10-28 14:43:27 +01:00
evgeny 04b76be1c8 Compile the battery permission adapter in Android host tests 2026-10-28 14:43:27 +01:00
evgeny ff08f05e9a Model power exemption queries and system activity launch failures 2026-10-28 14:43:27 +01:00
evgeny 4b221ef0d1 Verify growing call preview and emphasized metric values 2026-10-28 14:35:46 +01:00
evgeny 859f33b5e9 Expand call preview to the available window area and emphasize diagnostic values 2026-10-28 14:34:12 +01:00
evgeny b03d101c87 Check call diagnostics, avatar visibility and bottom action alignment 2026-10-28 14:20:36 +01:00
evgeny 309754244a Localize call diagnostics and keep video parameters in logs 2026-10-28 14:20:36 +01:00
evgeny b82e9cc98e Pin call actions to the bottom and add a separate diagnostics toggle 2026-10-28 14:19:14 +01:00
evgeny 264a13705f Finalize shared frame rate selection and deterministic call control verification 2026-10-28 14:10:53 +01:00
evgeny bb0fa13c8b Show audio output captions and validate the desktop call settings menus 2026-10-28 14:08:21 +01:00
evgeny 2540909fda Replace desktop call settings with compact capture control menus 2026-10-28 14:06:40 +01:00
evgeny f76aacfba1 Share resolution dependent frame rate menus for capture settings 2026-10-28 14:04:31 +01:00
evgeny f9c150b7d4 Share capture control menus and Android style glyphs between desktop windows 2026-10-28 14:02:39 +01:00
evgeny 7be5c8bd0b Verify rendered control sizes and muted stream startup 2026-10-28 13:57:05 +01:00
evgeny 287b54b283 Allow and remember stream audio toggling before publication starts 2026-10-28 13:55:45 +01:00
evgeny c932528217 Apply initial stream mute before opening capture devices 2026-10-28 13:55:15 +01:00
evgeny 26953fc1a4 Render broadcast controls at their actual icon size with Android style values and rotation 2026-10-28 13:55:14 +01:00
evgeny 01dd40fdd1 Double broadcast control icons and tighten button spacing 2026-10-28 13:47:09 +01:00
evgeny 07b8c2b338 Keep broadcast menu style alive through menu teardown and add English labels 2026-10-28 13:44:02 +01:00
evgeny 21ab92d2b4 Update broadcast control tests and Russian menu labels 2026-10-28 13:42:58 +01:00
evgeny 35875a2c43 Move desktop broadcast settings into compact top menus with separate resolution and FPS 2026-10-28 13:41:09 +01:00
evgeny 7d3f0852f7 Place video settings in the centered desktop call control row 2026-10-28 13:25:24 +01:00
evgeny f1da7e1837 Center desktop call actions and use a gear button for video settings 2026-10-28 13:17:19 +01:00
evgeny 75336387c5 Translate desktop video settings and camera toggles 2026-10-28 13:09:42 +01:00
evgeny 858e27ec8c Replace desktop call video checkbox with a round camera button 2026-10-28 13:09:42 +01:00
evgeny 270eb0c3b0 android: add photo and video capture orientation controls 2026-10-28 12:58:21 +01:00
evgeny 19a3cc8934 Merge remote-tracking branch 'origin/master' 2026-10-28 12:43:38 +01:00
evgeny f9ccca85bb Insert generated config fields before blank section separators 2026-10-28 12:41:10 +01:00
evgeny 41930a35c4 Audit configuration sample against current parser and service behavior 2026-10-28 12:36:21 +01:00
evgeny 2c82ceaad7 Handle nullable multicast lock creation before acquiring ownership 2026-10-28 12:28:28 +01:00
evgeny 3c5a9410ec Clarify retained LAN delivery state after core shutdown 2026-10-28 12:28:28 +01:00
evgeny 25dda68ecf Document LAN invitation framing and server link preview contracts 2026-10-28 12:28:28 +01:00
evgeny 237ba93e1a Report invitation presentation errors without exposing link secrets 2026-10-28 12:28:28 +01:00
evgeny 6f9ddc88e2 Add localized invitation copy errors and delivery recipient labels 2026-10-28 12:28:28 +01:00
evgeny f910d235fd Validate LAN events and retain multicast lock ownership on errors 2026-10-28 12:28:28 +01:00
evgeny 0be56a133b Reproduce LAN invitation state and multicast ownership failures 2026-10-28 12:28:28 +01:00
evgeny 0b8caaa810 Model LAN invitation JNI calls and multicast lock failures 2026-10-28 12:28:28 +01:00
evgeny e32e4be28b Document JNI log encoding and failure containment contracts 2026-10-28 12:28:28 +01:00
evgeny c137ad89d1 Clarify JNI log scenario coverage and callback descriptor checks 2026-10-28 12:28:28 +01:00
evgeny 1c705e64ca Verify repeated JNI delivery and log subscription changes 2026-10-28 12:28:28 +01:00
evgeny 269d09815b Document JNI host checks and their platform requirements 2026-10-28 12:28:28 +01:00
evgeny 0931eeedad Run JNI log fault scenarios with Android unit tests 2026-10-28 12:28:28 +01:00
evgeny a77fc553e7 Contain JNI logging failures and preserve UTF-8 payloads 2026-10-28 12:28:28 +01:00
evgeny c656e3a96b Reproduce Android JNI log callback failures on the host 2026-10-28 12:28:28 +01:00
evgeny 8268c5112c Describe Android log retention and diagnostic output contracts 2026-10-28 12:28:28 +01:00
evgeny 401e65c132 Read Android log snapshots without losing queued updates 2026-10-28 12:28:28 +01:00
evgeny 69cb7664f3 Update chatserver sample for generated addition key 2026-10-28 12:26:35 +01:00
evgeny 38d24e7bbf Document opt-in Android network logging 2026-10-28 12:08:07 +01:00
evgeny 0c2b96ee95 Add a logreceiver checkbox to Android debug settings 2026-10-28 12:08:07 +01:00
evgeny 0a36dc5ac6 Make Android UDP log forwarding opt-in with a persisted target 2026-10-28 12:08:07 +01:00
evgeny 917a2a2b28 Serialize stream capture preferences with other saved media profiles 2026-10-28 12:08:07 +01:00
evgeny 7ed8f90068 Keep call controls visible while a video menu is open 2026-10-28 12:08:07 +01:00
evgeny c0acb6b268 Remember separate photo and video recording preferences 2026-10-28 12:08:07 +01:00
evgeny c9f8f17858 Restore video call modes and remember the selected bitrate range 2026-10-28 12:08:07 +01:00
evgeny 76f81bc14e Store independent capture profiles in the application settings queue 2026-10-28 12:08:07 +01:00
evgeny 9f1c1cf9e4 Add titled one-tap menus to stream capture and audio controls 2026-10-28 12:08:07 +01:00
evgeny 211f8f4c5d Keep the video bitrate slider aligned with its saved range 2026-10-28 12:08:07 +01:00
evgeny c368b77a00 Unify video call controls and support one-tap option menus 2026-10-28 12:08:07 +01:00
evgeny ead884e6d3 Prefer the main rear camera in photo mode 2026-10-28 12:08:07 +01:00
evgeny 067a6bd801 Switch camera menus in one tap and toggle the current menu 2026-10-28 12:08:07 +01:00
evgeny 217a4bb27b Add descriptive headers to camera option menus 2026-10-28 12:08:07 +01:00
evgeny 93da173987 Default camera JPEG quality to 85 and remove lowest presets 2026-10-28 12:08:07 +01:00
evgeny a53668ade8 Show captured JPEG file size and enlarge camera metadata text 2026-10-28 12:08:07 +01:00
evgeny 07c9cf223c Hide camera discard and send actions until there is captured media 2026-10-28 12:08:07 +01:00
evgeny f351f289af Center camera actions and replace inactive shutter with a half-width gap 2026-10-28 12:08:07 +01:00
evgeny 22c8f9a69c Place compact photo and video details beside camera controls 2026-10-28 12:08:07 +01:00
evgeny 1359247e3f Describe recording codec checks and JPEG quality preview 2026-10-28 12:08:07 +01:00
evgeny c7b301b3a1 Document updated Android build stack and keep capture diagnostics compact 2026-10-28 12:08:07 +01:00
evgeny 03059e3001 Choose recording codec, resolution and bitrate independently and set JPEG quality 2026-10-28 12:08:07 +01:00
evgeny afa6af5012 Share compact bitrate labels between streaming and recording controls 2026-10-28 12:08:06 +01:00
evgeny aaf0617a1f Upgrade Android build tools and CameraX while retaining API 26 minimum 2026-10-28 12:08:06 +01:00
evgeny b84561dba5 Use shared capture icons and menus for camera and resolution selection 2026-10-28 12:08:06 +01:00
evgeny 379e7731df Align Android camera timer to the right of the control panel 2026-10-28 12:08:06 +01:00
evgeny 4aa5513f25 Keep Android camera settings and controls outside the preview 2026-10-28 12:08:06 +01:00
evgeny 10a4554c81 Localize desktop image validation errors 2026-10-28 12:08:06 +01:00
evgeny c84c328c90 Align camera navigation and developer references with shared capture screen 2026-10-28 12:08:06 +01:00
evgeny 4f5e46e9a9 Keep cache sources alive while accepted legacy image copies are pending 2026-10-28 12:08:06 +01:00
evgeny 2ac483f10f Document image attachment metadata and shared Android camera ownership 2026-10-28 12:08:06 +01:00
evgeny 199eaa0429 Verify desktop image previews decode asynchronously and paint without file I/O 2026-10-28 12:08:06 +01:00
evgeny 154c76068c Check encrypted image dimensions across the Android bridge 2026-10-28 12:08:06 +01:00
evgeny b3e7db7b26 Cover encrypted group images and fixed private generation in desktop submission tests 2026-10-28 12:08:06 +01:00
evgeny 206abcae10 Test typed desktop images in channels and PM and reject corrupted attachments 2026-10-28 12:08:06 +01:00
evgeny 3c74fc89fe Handle camera cache failures and remove unused photo submission wrapper 2026-10-28 12:08:06 +01:00
evgeny 684062c115 Test image metadata, private attachment publication and Android cache ownership 2026-10-28 12:08:06 +01:00
evgeny c6fdf52582 Decode desktop image previews in bounded background jobs 2026-10-28 12:08:06 +01:00
evgeny 08e9b62e16 Render image previews from prepared model data and preserve aspect ratios 2026-10-28 12:08:06 +01:00
evgeny 04d9d1f2b9 Connect shared camera and photo viewer to Android channel and PM navigation 2026-10-28 12:08:06 +01:00
evgeny 6e30fd474e Unify Android photo and video capture with explicit cache ownership 2026-10-28 12:08:06 +01:00
evgeny 8ff6694c5a Show bounded image previews and open zoomable photos in Android private chats 2026-10-28 12:08:06 +01:00
evgeny d1bb143928 Add localized image and camera error states 2026-10-28 12:08:06 +01:00
evgeny 4228f37cf5 Recognize image contents and preserve image dimensions in Android conversations 2026-10-28 12:08:06 +01:00
evgeny 233a3f78d1 Pass image MIME and private conversation generation through Android JNI 2026-10-28 12:08:06 +01:00
evgeny e4af3907c2 Prepare Android JPEG and PNG attachments for fixed channel or PM targets 2026-10-28 12:08:06 +01:00
evgeny 23fecc2c11 Send and display JPEG and PNG in desktop private conversations 2026-10-28 12:08:06 +01:00
evgeny e3b09bd0b7 Support JPEG and PNG attachment metadata and preparation 2026-10-28 12:08:06 +01:00
evgeny 78ea57d183 Clarify conversation rendering and preserve quote Unicode 2026-10-28 11:36:13 +01:00
evgeny 0b285ec19b Move the logs shortcut beside the CPU indicator 2026-10-28 11:36:13 +01:00
evgeny 8b3b6fb5af Reject malformed feedback events before updating UI state 2026-10-28 11:36:13 +01:00
evgeny 317f362a7a Reproduce malformed feedback event handling in the UI 2026-10-28 11:36:13 +01:00
evgeny a1ce486e89 Document feedback snapshots and poll UI submission contracts 2026-10-28 11:36:13 +01:00
evgeny 37515df8c1 Validate poll drafts and reject malformed feedback snapshots 2026-10-28 11:36:13 +01:00
evgeny 89efd10450 Reproduce invalid poll draft and inactive custom answer handling 2026-10-28 11:36:13 +01:00
evgeny f6b5e5b42c Route group avatar snapshots separately from feedback changes 2026-10-28 11:36:13 +01:00
evgeny d969b277e1 Assign a registered event ID to Android group avatar snapshots 2026-10-28 11:36:13 +01:00
evgeny e91987d241 Reproduce Android avatar and feedback event ID collision 2026-10-28 11:36:13 +01:00
evgeny 69bc182ee9 Clarify capture timeline and microphone permission contracts 2026-10-28 11:36:13 +01:00
evgeny c0c282ca3a Make voice recording ownership and playback failures explicit 2026-10-28 11:36:13 +01:00
evgeny 0219624c7d Reproduce voice capture rollback and playback cleanup failures 2026-10-28 11:36:13 +01:00
evgeny 537814e7fd Model microphone permission for voice recorder host tests 2026-10-28 11:36:13 +01:00
evgeny c31bdf74d8 Add host audio output controls for voice recorder failures 2026-10-28 11:36:13 +01:00
evgeny 5db51e64de Retry file resource cleanup when the core stops 2026-10-28 11:36:13 +01:00
evgeny a8c9bc6049 Document file browser lifecycle and export error handling 2026-10-28 11:36:13 +01:00
evgeny 0aa63c98ee Document Android file framing and error status contracts 2026-10-28 11:36:13 +01:00
evgeny 5290a2868d Preserve file wake lock ownership and isolate cleanup errors 2026-10-28 11:36:13 +01:00
evgeny 4f06b4bca9 Reproduce file cleanup failures and verify native cancellation 2026-10-28 11:36:13 +01:00
evgeny f60390c99c Model native file failures and wake lock ownership on host 2026-10-28 11:36:13 +01:00
evgeny 529237dfc8 Add host document providers for file failure tests 2026-10-28 11:36:13 +01:00
evgeny 84e4667f5c Describe avatar gallery and EXIF decoding behavior 2026-10-28 11:36:13 +01:00
evgeny 81f36d15c8 Clarify avatar editor ownership and UI publication state 2026-10-28 11:36:13 +01:00
evgeny 977992e834 Document Android avatar storage and publication contracts 2026-10-28 11:36:13 +01:00
evgeny 6f8baf82c7 Clarify Android playback recovery and diagnostics contracts 2026-10-28 11:36:13 +01:00
evgeny 00f8d8aeb0 Document Android call audio I/O and clock contracts 2026-10-28 11:36:13 +01:00
evgeny 7e502f9dd3 Verify headless server link commands and self-add rejection 2026-10-28 11:17:28 +01:00
evgeny 52dadf8b23 Document server link generation and channel addition commands 2026-10-28 11:13:34 +01:00
evgeny f1ff394f83 Document server authorization contract and cover cancellation lifecycle 2026-10-28 11:10:27 +01:00
evgeny bc296af99f Test server link presentation and authorization errors in clients 2026-10-28 11:07:58 +01:00
evgeny 3daacc07b7 Select any joined channel when opening an Android server link 2026-10-28 11:06:24 +01:00
evgeny f2d6561509 Route Android server links through channel selection and ordinary JOIN request 2026-10-28 11:05:23 +01:00
evgeny a9cc6785a9 Expose authorized server addition to Android JNI 2026-10-28 11:04:56 +01:00
evgeny f606c65858 Choose a local channel when opening a server link 2026-10-28 11:03:18 +01:00
evgeny 031b8b086b Accept server links in channel invitation dialog 2026-10-28 11:03:00 +01:00
evgeny 667cd1b302 Expose server link kind and authorization failures in Qt 2026-10-28 11:02:59 +01:00
evgeny 3c2c8978df Test authorized server JOIN over UDP and persistent addition keys 2026-10-28 11:01:35 +01:00
evgeny 3bc3e86529 Expose server links and channel addition through headless control 2026-10-28 10:59:16 +01:00
evgeny 7374b59c03 Authorize server join requests and run ordinary channel JOIN 2026-10-28 10:58:25 +01:00
evgeny 759a576a8d Build server links from shared codec and published endpoints 2026-10-28 10:56:09 +01:00
evgeny 0b6a882480 Persist generated server addition credentials in configuration 2026-10-28 10:55:50 +01:00
evgeny bd50140d26 Add explicit server and channel link kinds to shared codec 2026-10-28 10:55:25 +01:00
evgeny b773656dad Fix Windows entry point definitions in desktop GUI tests 2026-10-28 01:51:09 +01:00
evgeny 1ad00c12ad Fix attachment sending, media manifests and storage defaults 2026-10-28 01:47:17 +01:00
evgeny b86dcdd926 Fix member detail test bridge stubs after member editing API changes 2026-10-28 01:20:18 +01:00
evgeny 0ce248eb4a Configure recording compressor and provide a valid shutdown test identity 2026-10-28 00:59:00 +01:00
evgeny 65f39b6bae Test compressed recording rejection and ordered MainWindow shutdown 2026-10-28 00:59:00 +01:00
evgeny fee528194b Handle the tracked voice view during destruction and isolate test startup work 2026-10-28 00:59:00 +01:00
evgeny f624fd6a75 Clarify SQLite snapshot lifetime during desktop teardown 2026-10-28 00:59:00 +01:00
evgeny 15ca1047ce Cover desktop queue, attachment, DM, SQLite and media regressions 2026-10-28 00:59:00 +01:00
evgeny 9ee64d9a9f Extend desktop command regression suite and verify SQLite stopping handoff 2026-10-28 00:59:00 +01:00
evgeny 72f4258410 Replace stale desktop architecture documentation and honor the temporary directory 2026-10-28 00:59:00 +01:00
evgeny b4553db769 Reset selected GUI state during teardown and keep CHAT read watermarks separate from PM sequences 2026-10-28 00:59:00 +01:00
evgeny d5f5cf407a Finish desktop header ownership, state and model role contracts 2026-10-28 00:59:00 +01:00
evgeny 17772163cd Complete MainWindow and MessageList contracts for commands and snapshots 2026-10-28 00:59:00 +01:00
evgeny 7556695cc5 Guard desktop modal owners and remove obsolete message helpers 2026-10-28 00:59:00 +01:00
evgeny 8b2b68d383 Own feedback requests and fence poll dialogs to their channel and lifetime 2026-10-28 00:59:00 +01:00
evgeny d0bf402824 Document checked desktop snapshots and require matching media click gestures 2026-10-28 00:59:00 +01:00
evgeny 0942bf3d24 Use the running profile database directory for desktop media paths 2026-10-28 00:59:00 +01:00
evgeny b87050900c Deduplicate channel voice playback and resolve encrypted media snapshots 2026-10-28 00:59:00 +01:00
evgeny 6adfe5cf13 Centralize owned attachment downloads and key auto-play by channel and row 2026-10-28 00:59:00 +01:00
evgeny 0d6fd63e8f Return attachment metadata as checked SQLite snapshots 2026-10-28 00:59:00 +01:00
evgeny 034df2939c Reject incomplete DB reads and clock voice progress from PCM outside paint 2026-10-28 00:59:00 +01:00
evgeny 1235f770eb Fence deferred message actions, release voice views and flush state before shutdown 2026-10-28 00:59:00 +01:00
evgeny adefef675c Detach GUI SQLite readers before worker teardown 2026-10-28 00:59:00 +01:00
evgeny ce133a6acf Remove obsolete desktop DB sync and GUI writes and enforce read-only queries 2026-10-28 00:59:00 +01:00
evgeny f87ee63a1d Preserve failed composer drafts and cancel PM submissions with a result 2026-10-28 00:59:00 +01:00
evgeny 9d48821af2 Own message list requests and acknowledge PM text persistence 2026-10-28 00:59:00 +01:00
evgeny 4c1512cb78 Release unsubmitted media resources and own desktop channel and PM requests 2026-10-28 00:59:00 +01:00
evgeny 707938d503 Bind remaining desktop commands atomically and cancel owned attachments 2026-10-28 00:59:00 +01:00
evgeny d9abb1f025 Exercise both native owners throughout concurrent radio rebinding 2026-10-28 00:59:00 +01:00
evgeny 6063d3eb2c Include the chat service API in the radio command fixture 2026-10-28 00:59:00 +01:00
evgeny 27388c1137 Link the radio command GUI test to Windows COM support 2026-10-28 00:59:00 +01:00
evgeny bc78e0889a Route MainWindow radio invitations through owned commands and test them 2026-10-28 00:59:00 +01:00
evgeny 0f36248d1e Own and bind desktop radio call commands inside the bridge 2026-10-28 00:59:00 +01:00
evgeny 87b971569e Check command ownership independently of the uasync timer pool 2026-10-28 00:59:00 +01:00
evgeny 85172f3ac0 Include miniaudio types for the settings test audio backend 2026-10-28 00:59:00 +01:00
evgeny 096c613666 Own MainWindow UI state requests through the settings bridge 2026-10-28 00:59:00 +01:00
evgeny 95e59df5c7 Complete call window header contracts and align test data rows 2026-10-28 00:59:00 +01:00
evgeny fd4f092c9a Decline incoming calls when closing their window and verify teardown 2026-10-28 00:59:00 +01:00
evgeny 9ef188b0d3 Link call command tests against the camera and codec modules 2026-10-28 00:59:00 +01:00
evgeny de60f8fb15 Translate call command queue errors 2026-10-28 00:59:00 +01:00
evgeny e23a7e27eb Test call command ownership, allocation failures and core rebinding 2026-10-28 00:58:59 +01:00
evgeny f3d18a57b5 Use owned call start and audio failure hangup from the main window 2026-10-28 00:58:59 +01:00
evgeny 299c1b86f8 Send call window actions through the owned bridge API 2026-10-28 00:58:59 +01:00
evgeny 4b4f48963e Own desktop call commands and bind them atomically to the core 2026-10-28 00:58:59 +01:00
evgeny 138f6071b0 Guard capture-only image queue and test publication without Multimedia 2026-10-28 00:58:59 +01:00
evgeny fe7cd73646 Document asynchronous desktop stream publication and settings 2026-10-28 00:58:59 +01:00
evgeny cb95cf7d27 Document desktop file and live player window contracts 2026-10-28 00:58:59 +01:00
evgeny cfa53af3a3 Translate video playback seek and read errors 2026-10-28 00:58:59 +01:00
evgeny 71f5cc9c94 Preserve early seek position and document playback lifecycle 2026-10-28 00:58:59 +01:00
evgeny e371cc4dd9 Cover audio tail pause, replay, seeking and queued EOF callbacks 2026-10-28 00:58:59 +01:00
evgeny ab37a06dad Follow PCM node completion and keep seeking and replay consistent 2026-10-28 00:58:59 +01:00
evgeny 7fe90be7b2 Expose PCM drain state and cursor while file playback waits at EOF 2026-10-28 00:58:59 +01:00
evgeny d8109770a0 Finish file playback only after video presentation and PCM drain 2026-10-28 00:58:59 +01:00
evgeny 4118149dbc Reproduce file playback completion before queued media is presented 2026-10-28 00:58:59 +01:00
evgeny 7b3fe48657 Verify caption updates preserve continuous H264 and Opus playback 2026-10-28 00:58:59 +01:00
evgeny 5286388ada Refresh multiview names without recreating stream tiles 2026-10-28 00:58:59 +01:00
evgeny 3ff5ca7009 Update live player captions independently of playback state 2026-10-28 00:58:59 +01:00
evgeny 9d2ddcc496 Reproduce stale stream captions without restarting playback 2026-10-28 00:58:59 +01:00
evgeny debd3b45ef Clarify preview validity and publisher audio state responsibilities 2026-10-28 00:58:59 +01:00
evgeny a03abcaa02 Describe multiview tile lifetime, navigation and retry contracts 2026-10-28 00:58:59 +01:00
evgeny 1f0c7483e0 Describe stream bridge ownership, asynchronous requests and snapshots 2026-10-28 00:58:59 +01:00
evgeny 3960e28638 Document portal capture setup, frame lifetime and deferred shutdown 2026-10-28 00:58:59 +01:00
evgeny d9eab97dee Describe cursor overlay coordinates, thread ownership and outcomes 2026-10-28 00:58:59 +01:00
evgeny 615bdda36e Document QP sampling and atomic stream source snapshot parsing 2026-10-28 00:58:59 +01:00
evgeny ce4ff084cc Target transfer allocation faults after the file dialog closes 2026-10-28 00:58:59 +01:00
evgeny e05df14371 Keep file lifecycle test data isolated and suppress expected poll stalls 2026-10-28 00:58:59 +01:00
evgeny 07d9c17dec Check empty file cancellation and keep test capture semantics aligned 2026-10-28 00:58:59 +01:00
evgeny 0419c83ab0 Use file bridge cancellation without browser forwarding helpers 2026-10-28 00:58:59 +01:00
evgeny b04b262174 Cancel file batch commands directly through the owned bridge 2026-10-28 00:58:59 +01:00
evgeny 59cd456386 Allow cancellation of an empty file operation as a no-op 2026-10-28 00:58:59 +01:00
evgeny ba44e243a9 Verify file command success against the real storage service 2026-10-28 00:58:59 +01:00
evgeny 83f8b0cbe2 Cover file snapshots, cancellation ownership and browser retries 2026-10-28 00:58:59 +01:00
evgeny 656d64ae74 Adapt member file browser capture tests to snapshot APIs 2026-10-28 00:58:59 +01:00
evgeny bc90e88e72 Complete file browser operations when command posting fails 2026-10-28 00:58:59 +01:00
evgeny 7d789f68d4 Own desktop file commands and report cancellation through Qt 2026-10-28 00:58:59 +01:00
evgeny 142278d651 Reproduce cancelled and rejected desktop file commands 2026-10-28 00:58:59 +01:00
evgeny 7a4ce5d476 Clarify member file snapshots and browser helper contracts 2026-10-28 00:58:59 +01:00
evgeny 897da82b35 Document desktop member file batch and browser contracts 2026-10-28 00:58:59 +01:00
evgeny 8a831a0ed5 Remove deleted media blocks from the desktop module inventory 2026-10-28 00:58:59 +01:00
evgeny 5b07edcd98 Remove unused legacy media block reader and splitter 2026-10-28 00:58:59 +01:00
evgeny 4d2b59cb20 Disconnect unused legacy media blocks from desktop builds 2026-10-28 00:58:59 +01:00
evgeny b7ca74d61d Clarify link callback captures and their lifetime requirements 2026-10-28 00:58:59 +01:00
evgeny 25f0e21fb9 Document history selection state and delegate, link and scrolling contracts 2026-10-28 00:58:59 +01:00
evgeny b95fd63c46 Clarify the frozen attachment snapshot and shared submission diagnostics 2026-10-28 00:58:59 +01:00
evgeny 73a5366f1c Make regression callback cleanup safe after failed assertions 2026-10-28 00:58:59 +01:00
evgeny 58c2b5644d Translate the shared channel send failure message 2026-10-28 00:58:59 +01:00
evgeny 939b458c33 Check synchronous attachment handlers cannot redirect or access a deleted composer 2026-10-28 00:58:59 +01:00
evgeny 45485f4fbc Use one owned channel submission path and preserve the emitting context 2026-10-28 00:58:59 +01:00
evgeny 195b9c5afb Keep send fault injection and callback lifetimes isolated in tests 2026-10-28 00:58:59 +01:00
evgeny 48a6f03d78 Cover channel send success, retry, cancellation and allocation failures end to end 2026-10-28 00:58:59 +01:00
evgeny 143fd51791 Transfer channel text requests through the owned composer bridge 2026-10-28 00:58:59 +01:00
evgeny 4d18a7015d Report cancelled composer submissions before releasing their owned requests 2026-10-28 00:58:59 +01:00
evgeny 3c5e52a630 Keep ordinary channel drafts until their correlated save result 2026-10-28 00:58:59 +01:00
evgeny 9be3c4af48 Reproduce ordinary draft loss and missing cancellation acknowledgments 2026-10-28 00:58:59 +01:00
evgeny 88760510da Document composer acknowledgments, attachment ownership and context snapshots 2026-10-28 00:58:59 +01:00
evgeny cdaad39cf2 Verify corrected emoji insertion through the real composer connection 2026-10-28 00:58:59 +01:00
evgeny 214af09510 Correct emoji catalog mappings and log selected Unicode bytes 2026-10-28 00:58:59 +01:00
evgeny 5f90557a36 Reproduce emoji label mismatches through real picker selections 2026-10-28 00:58:59 +01:00
evgeny d0755477f2 Clarify parentless emoji panel sizing and tab icon drawing 2026-10-28 00:58:59 +01:00
evgeny b5d4c2be8b Describe category tab rendering and palette behavior 2026-10-28 00:58:59 +01:00
evgeny 62175e04a8 Document emoji catalog side effects and picker icon lifetimes 2026-10-28 00:58:59 +01:00
evgeny 8fddf854de Verify member save requests owner shutdown if rollback remains open 2026-10-28 00:58:59 +01:00
evgeny 1515a37b8a Verify fresh role snapshots and admin transfer cancellation ownership 2026-10-28 00:58:59 +01:00
evgeny b78fd7a8e6 Match editable roles to the same owner version read from SQLite 2026-10-28 00:58:59 +01:00
evgeny bc5e6aa5a5 Document cancellation acknowledgments for member edit commands 2026-10-28 00:58:59 +01:00
evgeny 8f02e1ec2d Read member edit capabilities and fields in one GUI snapshot 2026-10-28 00:58:59 +01:00
evgeny 84bf74e034 Limit commit fault injection to the member save transaction 2026-10-28 00:58:59 +01:00
evgeny f11ab51ccc Check stale forms, read failures and member command memory ownership 2026-10-28 00:58:59 +01:00
evgeny 49cbfe1ae0 Block property saves without a successfully read member snapshot 2026-10-28 00:58:59 +01:00
evgeny d73d62db48 Reject rename saves when the initial nickname read failed 2026-10-28 00:58:59 +01:00
evgeny 2d79023c5e Verify member save rollback across nickname SQL and owner changes 2026-10-28 00:58:59 +01:00
evgeny 279d7da51c Name member save status widgets for regression checks 2026-10-28 00:58:59 +01:00
evgeny f537f302c6 Exercise member dialogs against a real worker and SQLite failures 2026-10-28 00:58:59 +01:00
evgeny 5842855583 Confirm atomic member property saves before closing the dialog 2026-10-28 00:58:59 +01:00
evgeny 7e412d950a Bind owned admin transfer requests to the selected database 2026-10-28 00:58:59 +01:00
evgeny be11fbb8b6 Keep rename dialog open until the core confirms its write 2026-10-28 00:58:59 +01:00
evgeny 096e721faa Return correlated member save and cancellation results to live GUI contexts 2026-10-28 00:58:59 +01:00
evgeny 1431507ac5 Save member nicknames and owner changes in one core transaction 2026-10-28 00:58:59 +01:00
evgeny 30a15f6cfd Document audio settings snapshots and device test behavior 2026-10-28 00:58:58 +01:00
evgeny 005d136dc7 Make Android microphone capture stoppable and cleanup resilient
Use nonblocking AudioRecord reads with data and timestamp deadlines. Serialize idempotent close, finish interrupted joins before release, isolate callback failures, and abort stereo fallback when partial-record cleanup fails.

Close failed shared readers to new subscriptions, roll back worker startup, isolate observers, preserve interrupt state, and release the last consumer exactly once. Add an independent capture-tests JVM module to the standard Android unit-test task.

Validation: 38 capture scenarios (25 AudioRecord plus 13 PCM/PTT), 455 JVM tests, assembleDebug, core build, and full check.sh (225 tests plus proxy/burst/load) passed.
2026-10-28 00:53:01 +01:00
evgeny 74035fc043 Recover Android media audio sessions with explicit resource ownership
Retry monitor and capture setup after invalidating failed attempts. Bind output leases and callbacks to registration identity, cancel confirmation timers, and keep hardware cleanup independent from device enumeration during call handoff.

Commit profiles only after successful storage writes, acquire mode ownership before Android side effects, and reject blocking operations on main or the control worker. Keep the app singleton backed by an isolated MediaAudioSession with a single executor.

Validation: 30 media session scenarios, 420 JVM tests, assembleDebug, core build, and full check.sh (225 tests plus proxy/burst/load) passed.
2026-10-28 00:28:42 +01:00
evgeny a6ae4df3ff Harden Android audio router lifecycle and route selection
Roll back failed startup, finish independent stop cleanup, invalidate stale device and Telecom callbacks, and serialize router mutations. Publish input/output targets after accepted selection and support retries of rejected requests.

Separate modern communication device selection from legacy SCO, refresh replaced descriptors, and support A2DP and USB input-only devices in per-track mode. Clarify routing and observer ownership contracts.

Validation: 45 router scenarios, 390 JVM tests, assembleDebug, core build, and full check.sh (225 tests plus proxy/burst/load) passed. Previous router fails 25 of the 30 new cases.
2026-10-27 23:53:21 +01:00
evgeny 0d45bdbad6 Own Android incoming call alerts and notification actions
Bind notification tokens to full call IDs and call kinds, cancel actions on stop, and reject decline callbacks after ringing ends. Serialize alert state on main and recover notification channel setup after Android API failures.

Keep sound independent of wake-lock and notification failures. Remove orphaned notifications on cold start, preserve idempotent alerts during duplicate delivery and language changes, and document lifecycle contracts.

Validation: 32 new lifecycle cases, 360 JVM tests, assembleDebug, core build, and full check.sh (225 tests plus proxy/burst/load) passed.
2026-10-27 23:31:56 +01:00
evgeny 5a6eabf4fc Fix Android alert profiles and playback resource ownership
Configure audio attributes before MediaPlayer preparation, keep vibration independent from sound failures, and guard loop/focus cleanup against stale callbacks. Preserve ringback players on repeated phase requests.

Add 35 alert lifecycle tests against real Kotlin sources with controlled Android API failures. Validation: 328 JVM tests, assembleDebug, core build, and full check.sh (225 tests plus proxy/burst/load) passed. Previous sources fail 32 of the 35 new cases.
2026-10-27 23:12:11 +01:00
evgeny f4ef949482 Guard Android radio configuration with worker-owned tasks 2026-10-27 22:41:30 +01:00
evgeny f71aff3e11 Document Android radio automatic capture and background window contracts 2026-10-27 21:58:02 +01:00
evgeny d6dc6234d5 Recover SIM observers without losing healthy subscription state 2026-10-27 21:49:15 +01:00
evgeny 6a38eaa4eb Compile the real SIM monitor in the Android host tests 2026-10-27 21:39:26 +01:00
evgeny 6e6260ab29 Add controlled Telephony fixtures for Android SIM monitoring 2026-10-27 21:35:45 +01:00
evgeny 142cc1a7a1 Verify Android phone state publishing and JNI restart recovery 2026-10-27 21:30:07 +01:00
evgeny 4859d03f29 Return Android phone state queue acceptance through JNI 2026-10-27 21:25:51 +01:00
evgeny 067c1cd496 Own queued Android phone state data within the worker lifetime 2026-10-27 21:23:18 +01:00
evgeny 2b55d9225a Cover Android phone command cancellation and publication ownership 2026-10-27 21:21:52 +01:00
evgeny 9e679462d4 Expose Android phone state posting through the C bridge API 2026-10-27 21:18:29 +01:00
evgeny b92727e66a Make proximity observation safe across failures and restarts 2026-10-27 20:57:24 +01:00
evgeny 0d3ffb8736 Add a host sensor fixture for ProximityManager lifecycle checks 2026-10-27 20:54:40 +01:00
evgeny da85971969 Verify CoreActivity against Android JNI and native activity modes 2026-10-27 20:44:34 +01:00
evgeny ed1f4d8ea8 Preserve pending CoreActivity intent when the native queue rejects a request 2026-10-27 20:39:19 +01:00
evgeny f941066934 Cover rejected activity commands at the native queue boundary 2026-10-27 20:11:15 +01:00
evgeny 61266986e5 Route bridge activity requests through the worker owner 2026-10-27 20:10:00 +01:00
evgeny 4bece684da Queue Android activity updates while holding the worker lifetime lock 2026-10-27 20:07:51 +01:00
evgeny 1ed110d47c Validate CoreActivity ownership before mutations and cache completed JNI requests 2026-10-27 20:02:55 +01:00
evgeny b3b04b4d5a Add regressions for CoreActivity thread ownership and request caching 2026-10-27 19:53:53 +01:00
evgeny 29e6c977f2 Document Android worker cancellation and shutdown ownership 2026-10-27 19:30:29 +01:00
evgeny 64c1019a52 Verify cancelled Android workers retain callbacks and keep SQLite owned by the core 2026-10-27 19:30:29 +01:00
evgeny aca5f806c1 Keep worker callbacks atomic and verify failed shutdown preserves owners 2026-10-27 19:16:30 +01:00
evgeny 823bae076f Run Android service shutdown off the main thread and await it before startup 2026-10-27 19:07:05 +01:00
evgeny d6ea893f16 Preserve bridge callbacks until native worker shutdown succeeds 2026-10-27 18:57:36 +01:00
evgeny d83d58c874 Keep Android shutdown independent of a retiring service 2026-10-27 18:55:29 +01:00
evgeny 1c82432de9 Own Android worker threads until cleanup and join finish 2026-10-27 18:52:46 +01:00
evgeny 69b87ef3ed Verify Android startup readiness with the main looper and native worker 2026-10-27 18:33:49 +01:00
evgeny 11b3ceaa9b Wait for Android core readiness before applying settings 2026-10-27 18:27:14 +01:00
evgeny 8e0090b54b Track Android startup until native core readiness is confirmed 2026-10-27 18:20:48 +01:00
evgeny a09b67a70f Fix the key regeneration job type in ChatViewModel 2026-10-27 18:10:09 +01:00
evgeny 848247bde6 Exercise Android identity regeneration through JNI on devices 2026-10-27 18:08:29 +01:00
evgeny 50ea132c15 Recreate the Android core when regenerating its identity 2026-10-27 18:05:06 +01:00
evgeny 2ff51d0016 Persist Android identities atomically before updating config 2026-10-27 17:51:41 +01:00
evgeny 02ec6a50a5 Verify config saves survive cancellation of their submitting scope 2026-10-27 17:35:26 +01:00
evgeny 44f6d8a5bc Verify partial node reads and reject malformed address rows 2026-10-27 17:27:04 +01:00
evgeny 30a205340a Build node diagnostics from one checked SQLite snapshot 2026-10-27 17:27:04 +01:00
evgeny dc1f3260e3 Add node page snapshot and SQL failure regressions 2026-10-27 17:27:04 +01:00
evgeny d582f2ea77 Clarify settings dialog drafts, save semantics and borrowed dependencies 2026-10-27 17:27:04 +01:00
evgeny 2dd0970295 Document storage, network and database settings page contracts 2026-10-27 17:27:04 +01:00
evgeny 65c6bbc03b Distinguish optimize SQL completion from integrity check results 2026-10-27 17:27:04 +01:00
evgeny 6ba86bb1df Add SQLite and Qt database maintenance regression tests 2026-10-27 17:27:04 +01:00
evgeny 5233513fcc Remove unused settings test scaffolding 2026-10-27 17:27:04 +01:00
evgeny 8323be7272 Cover settings string limits, snapshots and late allocation failures 2026-10-27 17:27:04 +01:00
evgeny e3b0eebc2b Eliminate borrowed save commands from the desktop settings dialog 2026-10-27 17:27:04 +01:00
evgeny 4d3b294ee9 Remove borrowed audio settings commands and duplicated serialization 2026-10-27 17:27:04 +01:00
evgeny a1f925c789 Transfer storage settings snapshots through the owned bridge API 2026-10-27 17:27:04 +01:00
evgeny f1f5d33788 Centralize owned settings and name requests in the GUI bridge 2026-10-27 17:27:04 +01:00
evgeny 05b0ef50e4 Add real desktop settings save ownership regression tests 2026-10-27 17:27:04 +01:00
evgeny 5382b686e9 Keep config snapshots and network diagnostics precise 2026-10-27 17:18:13 +01:00
evgeny 893e714422 Show a specific error when database reset cannot finish 2026-10-27 17:18:13 +01:00
evgeny 3b42547740 Report native Android database cleanup failures accurately 2026-10-27 17:18:13 +01:00
evgeny b8e7b18937 Serialize Android config transactions and await them through UI lifecycles 2026-10-27 17:18:13 +01:00
evgeny 3ba581770c Build Android configuration from one preferences and key snapshot 2026-10-27 17:18:13 +01:00
evgeny 482026e208 Add an application-owned queue for atomic Android config writes 2026-10-27 17:18:13 +01:00
evgeny 78f34a3617 Clarify stream resource and voice route ownership wording 2026-10-27 15:25:33 +01:00
evgeny 4dc02d74b8 Document sound manager recovery, session ownership and callback rules 2026-10-27 15:23:38 +01:00
evgeny 027a4b4d9e Clarify desktop voice recording and playback contracts 2026-10-27 15:21:31 +01:00
evgeny 22460a1259 Merge remote-tracking branch 'origin/master' 2026-10-27 15:18:21 +01:00
evgeny 8d8fe8d6bf Fix sound settings request ownership on rejection and cancellation 2026-10-27 15:13:26 +01:00
evgeny 821f1b8a92 Add sound settings request ownership regressions 2026-10-27 15:11:22 +01:00
evgeny 6d925fecd1 Serialize Android network snapshots across monitor and core lifecycles 2026-10-27 15:04:27 +01:00
evgeny e3aa7839ae Include socket refresh monitoring in isolated host tests 2026-10-27 15:04:27 +01:00
evgeny 97a899c0c3 Model delayed network callbacks and config workers in host tests 2026-10-27 15:04:27 +01:00
evgeny 7b526ba681 Own Android network activity registrations across start and stop 2026-10-27 15:04:27 +01:00
evgeny f89c1975f7 Expose network activity callbacks to the isolated Android host tests 2026-10-27 15:04:27 +01:00
evgeny 8a22afc42d Add controlled host fixtures for Android network listeners 2026-10-27 15:04:27 +01:00
evgeny a6ab797659 Document audio device lifetime and voice worker contracts 2026-10-27 14:47:59 +01:00
evgeny eab9223f39 Clarify audio queue, capture clock and PCM reserve contracts 2026-10-27 14:43:24 +01:00
evgeny 799a71d361 Merge remote-tracking branch 'origin/master' 2026-10-27 14:32:36 +01:00
evgeny c7dadb0539 Clarify optional audio period and PTT latch release wording 2026-10-27 14:31:31 +01:00
evgeny 4389b511bf Align audio ownership comments with lease and recovery behavior 2026-10-27 14:28:02 +01:00
evgeny 29e2afc3ce Describe shared audio capture and buffer tuning contracts 2026-10-27 14:27:20 +01:00
evgeny cb49b9d4a4 Complete desktop radio UI and audio engine contracts 2026-10-27 14:24:46 +01:00
evgeny fb461cd56c Keep merged message link range documentation concise 2026-10-27 14:23:59 +01:00
evgeny 7f0c080492 Validate saved Android socket ports before reuse 2026-10-27 14:22:32 +01:00
evgeny 080c7a5fd5 Clarify Android auto socket identity and port reuse contracts 2026-10-27 14:22:32 +01:00
evgeny 0fe14699b0 Document Android conversation targets and test message ID conversion 2026-10-27 14:22:32 +01:00
evgeny 3d48024fd8 Trim desktop message link punctuation in linear time 2026-10-27 14:22:32 +01:00
evgeny f04637a257 Keep Android message link parsing linear and validate authority 2026-10-27 14:22:32 +01:00
evgeny 3e96e429eb Preserve unsigned node IDs in Android invite previews
Encode JNI node IDs as decimal strings and decode both uint64 fields without floating point or signed parsing. Compare all invitation fields and binary contents. Cover boundary IDs, malformed JSON types, and model equality with nine JVM tests. Native build, invite codec/build tests, and both debug APK ABIs passed.
2026-10-27 14:22:32 +01:00
evgeny 254029be63 Merge remote-tracking branch 'origin/master' 2026-10-27 14:19:09 +01:00
evgeny b5063f435b Explain radio settings reload and publication ordering 2026-10-27 14:12:49 +01:00
evgeny 0bac2566c9 Merge remote-tracking branch 'origin/master' 2026-10-27 14:11:47 +01:00
evgeny 8a96e5d1c7 Verify radio settings order during reentrant reload 2026-10-27 14:10:53 +01:00
evgeny 2226f54a56 Invalidate stale radio settings requests on reload 2026-10-27 14:08:22 +01:00
evgeny b4186dfae3 Cover radio settings recovery across core restarts 2026-10-27 14:06:05 +01:00
evgeny 0132a984dd Describe bounded control flow and corrected monitor behavior 2026-10-27 14:01:25 +01:00
evgeny cb50e268a4 Update monitor usage and asynchronous TCP architecture docs 2026-10-27 14:00:49 +01:00
evgeny 89c27b8fca Clarify control Action replies and graph display contracts 2026-10-27 14:00:49 +01:00
evgeny 4daa0e7f6b Document monitor TX ownership, deadlines and subscription bounds 2026-10-27 13:59:42 +01:00
evgeny 9e0cd3eddf Test control backpressure, snapshot mutations and deferred cleanup 2026-10-27 13:56:03 +01:00
evgeny 5c2ba74e3e Document desktop PTT chords and portal lifecycle 2026-10-27 13:54:55 +01:00
evgeny ae594e1e1b Test bounded monitor TCP sends and graph reconnect behavior 2026-10-27 13:47:41 +01:00
evgeny 488d8a601f Apply control TCP backpressure and stream node snapshots by ID 2026-10-27 13:46:01 +01:00
evgeny e9391c9790 Clarify desktop video modes and encoder output contracts 2026-10-27 13:43:00 +01:00
evgeny b1510ab437 Describe camera worker lifecycle and capture signals 2026-10-27 13:39:12 +01:00
evgeny ce06fe242b Queue monitor TCP commands and validate matched responses 2026-10-27 13:38:40 +01:00
evgeny 0594be9513 Document camera IPC framing and shared buffer ownership 2026-10-27 13:38:07 +01:00
evgeny 2d12dfb975 Correct monitor graph units and refresh cleared channel values 2026-10-27 13:34:04 +01:00
evgeny 4f27ce35a5 Fix control Action acknowledgements and validate command payloads 2026-10-27 13:33:13 +01:00
evgeny 6fdba59885 Correct cache cleanup glob documentation 2026-10-27 13:32:12 +01:00
evgeny 2d255afa6c Document avatar manager jobs and Lights Out behavior 2026-10-27 13:29:54 +01:00
evgeny 8691608924 Clarify avatar cache and image viewer contracts 2026-10-27 13:27:55 +01:00
evgeny fd80b35f8f Merge remote-tracking branch 'origin/master' 2026-10-27 13:17:50 +01:00
evgeny 7eaeb0e2f9 Preserve documentation audit and Android bridge fixes 2026-10-27 13:17:22 +01:00
evgeny ae4fb89bef Keep validation errors visible after explicit join attempts 2026-10-27 12:57:20 +01:00
evgeny d730dee925 Use accurate shared join errors and preserve result status 2026-10-27 12:56:13 +01:00
evgeny fcbec01c07 Translate shared join and offer failure messages 2026-10-27 12:55:13 +01:00
evgeny 16a68652ae Add UI regression tests for join and offer result errors 2026-10-27 12:53:47 +01:00
evgeny eca03747b3 Log desktop join and offer results with request context 2026-10-27 12:53:21 +01:00
evgeny b62ca4093e Report precise avatar editor source validation failures 2026-10-27 12:30:21 +01:00
evgeny 6c1b429e91 Check avatar editor coordinates after EXIF rotation 2026-10-27 12:29:20 +01:00
evgeny d72a2c092e Log avatar preparation generation and teardown state 2026-10-27 12:28:12 +01:00
evgeny 90d6f78a9e Resolve Qt 5 collection deduction in avatar and settings code 2026-10-27 12:26:58 +01:00
evgeny f54aa17e55 Observe buttonless pointer moves to cancel interrupted crop drags 2026-10-27 12:25:03 +01:00
evgeny 803d5f6583 Trace crop pointer state when a drag loses its button 2026-10-27 12:23:12 +01:00
evgeny 8c30c8e6ce Isolate avatar preparation generations and guard reentrant signals 2026-10-27 12:19:31 +01:00
evgeny d307492d22 Cover avatar preparation cancellation and reentrant owner deletion 2026-10-27 12:17:06 +01:00
evgeny b95d3628bf Check crop preview rendering and interrupted drags 2026-10-27 12:15:17 +01:00
evgeny 0a69864d10 Guard avatar upload controls across nested file and crop dialogs 2026-10-27 12:15:17 +01:00
evgeny 9c782be562 Bound avatar crop geometry and protect asynchronous preview lifetime 2026-10-27 12:10:36 +01:00
evgeny bfc280310d Cover avatar crop input bounds and modal owner lifetime 2026-10-27 12:07:36 +01:00
evgeny c25ed7c243 Report readable causes for malformed avatar blobs 2026-10-27 11:57:30 +01:00
evgeny 138de8d446 Document retryable avatar snapshot read failures 2026-10-27 11:57:30 +01:00
evgeny 90a588cfc1 Separate unpublished avatars from malformed published storage 2026-10-27 11:57:30 +01:00
evgeny 7d4da3a54d Treat an unpublished avatar as a successful empty read 2026-10-27 11:57:30 +01:00
evgeny a701580d54 Exercise main window destruction inside channel settings exec 2026-10-27 11:57:30 +01:00
evgeny bd105c630d Validate avatar read recovery and bounded typed blobs 2026-10-27 11:57:30 +01:00
evgeny 6106fc1b5d Keep transient SQLite failures out of the avatar cache 2026-10-27 11:57:30 +01:00
evgeny 905d30ceaf Distinguish failed avatar reads from committed empty blobs 2026-10-27 11:57:30 +01:00
evgeny 95e88ac66f Reproduce avatar cache poisoning after a transient SQL read error 2026-10-27 11:57:30 +01:00
evgeny 9fdd2dc9fb Specify the native channel ID range in GUI contracts 2026-10-27 11:57:30 +01:00
evgeny d4a969dc38 Match channel IDs to the native signed integer range 2026-10-27 11:57:30 +01:00
evgeny cf4a209837 Own group avatar commands and preserve pending result identity 2026-10-27 11:57:30 +01:00
evgeny 6c0aa98508 Cover group avatar publication ownership and result correlation 2026-10-27 11:57:30 +01:00
evgeny ddb373d445 Exercise settings retries and deletion changes during confirmation 2026-10-27 11:57:30 +01:00
evgeny cba3f4f75a Translate channel settings availability and queue errors 2026-10-27 11:57:30 +01:00
evgeny 3c6200f9c3 Keep channel settings alive safely across the main window loop 2026-10-27 11:57:30 +01:00
evgeny 74bcf91407 Own channel settings requests and guard nested dialogs 2026-10-27 11:57:30 +01:00
evgeny 271cfcd2f8 Cover channel settings queue failures and nested dialog lifetime 2026-10-27 11:57:30 +01:00
evgeny f12c7d072a test(chat): read complete media manifests with JSON whitespace 2026-10-27 11:48:09 +01:00
evgeny 9b24c1f012 fix(chat): preserve media and local state on incomplete database reads 2026-10-27 11:48:09 +01:00
evgeny 7c050eb7ef fix(chat): publish complete peer caches and clean pending JOIN state 2026-10-27 11:48:09 +01:00
evgeny ce3287ac94 fix(chat): verify incoming JOIN profiles before local insertion 2026-10-27 11:48:09 +01:00
evgeny 054ade0dcd fix(chat): select invite peers and read signed addresses consistently 2026-10-27 11:48:09 +01:00
evgeny 1efd8fb26c fix(chat): validate headless requests and complete media replies safely 2026-10-27 11:48:09 +01:00
evgeny c73090759f fix(chat): commit global names with signed node and member profiles 2026-10-27 11:48:09 +01:00
evgeny 0656f24a7c fix(chat): own Whisper jobs per instance and defer route UI events 2026-10-27 11:48:09 +01:00
evgeny cb9c04ff61 test(chat): distinguish route event deletion flag from routing API 2026-10-27 11:48:09 +01:00
evgeny 33556fefea test(chat): exercise channel deletion from a topology notification 2026-10-27 11:48:09 +01:00
evgeny 189ae43a7c docs(chat): distinguish committed core readiness from complete service startup 2026-10-27 11:48:09 +01:00
evgeny a4edd34695 fix(chat): retain SQL error codes when SQLite supplies no message 2026-10-27 11:48:09 +01:00
evgeny e28386c868 fix(chat): reject outer transactions before preparing shared service resources 2026-10-27 11:48:09 +01:00
evgeny 8151fc5a9c test(chat): cover startup admission, saved channel activation, and owner-close recovery 2026-10-27 11:48:09 +01:00
evgeny 1c6d203754 fix(chat): diagnose channel catalog failures with SQL status and shape 2026-10-27 11:48:09 +01:00
evgeny fb7846780b test(chat): verify startup metadata rollback and required callback allocation failures 2026-10-27 11:48:09 +01:00
evgeny 3b0ae79527 refactor(chat): keep the chat identity bound to its core instance 2026-10-27 11:48:09 +01:00
evgeny 6c777d4426 fix(chat): reject inconsistent repeated core initialization 2026-10-27 11:48:09 +01:00
evgeny 63406a9742 refactor(chat): borrow SQLite exclusively from the running core 2026-10-27 11:48:09 +01:00
evgeny 6f9723f8ce fix(chat): commit startup metadata before activating channels and publishing readiness 2026-10-27 11:48:09 +01:00
evgeny e3bd66f0b7 test(chat): reproduce ready startup after a required subscription fails 2026-10-27 11:48:09 +01:00
evgeny ed00f1ad9a fix(chat): require both member notification subscriptions at startup 2026-10-27 11:48:09 +01:00
evgeny 1aface994f fix(routing): report nodeinfo subscription allocation failure 2026-10-27 11:48:09 +01:00
evgeny 6429d4ca23 Merge desktop audit with updated chat contracts
Keep the complete member snapshot limit at 65535 and preserve SQL finalization checks, unsigned sorting, and owned GUI commands. Retain dynamic ETCP diagnostics with checked event lengths and no partial event on allocation failure. Validated three native and six GUI test targets and rebuilt vibechat.
2026-10-27 11:12:51 +01:00
evgeny c7618ba62b Limit group autoconnect indicators to group rows 2026-10-27 10:59:43 +01:00
evgeny 20ffa3fc6c Include the channel event byte type explicitly 2026-10-27 10:59:01 +01:00
evgeny 842083cdeb Exercise valid and stale channel menu actions 2026-10-27 10:57:21 +01:00
evgeny 1e3633ee56 Document channel list lifetime and validate row counters 2026-10-27 10:56:43 +01:00
evgeny 8552cf8316 Update isolated channel consumers for owned bridge requests 2026-10-27 10:56:43 +01:00
evgeny abc2f8efb6 Preserve channel state and own presence requests safely 2026-10-27 10:55:11 +01:00
evgeny 4d4fafc00b Isolate channel request cancellation from core startup tasks 2026-10-27 10:54:26 +01:00
evgeny 50fff66412 Cover channel reload state and pending request ownership 2026-10-27 10:53:23 +01:00
evgeny f81f6299b4 Bound channel row painting and support pixel-sized fonts 2026-10-27 10:51:20 +01:00
evgeny 282bf99d4a Cover channel delegate paint bounds and pixel fonts 2026-10-27 10:50:18 +01:00
evgeny 2822fa53e3 Clarify member snapshot output and boundary test contracts 2026-10-27 10:44:53 +01:00
evgeny 6104086d5b Bound member snapshot events and sort roster without quadratic copies 2026-10-27 10:37:33 +01:00
evgeny 34a95b7733 Route member diagnostics safely across panels and modal actions 2026-10-27 10:20:07 +01:00
evgeny a8958865bc Keep member rows consistent and own queued refresh requests 2026-10-27 09:48:38 +01:00
evgeny 6390c5db6a docs(chat): record preference full suite and GUI persistence validation 2026-10-27 07:37:41 +01:00
evgeny ee37cf0a55 docs(chat): record committed preference behavior and regression evidence 2026-10-27 07:34:44 +01:00
evgeny 655733e272 docs(chat): define preference return codes and bounded trampoline inputs 2026-10-27 07:33:08 +01:00
evgeny 89e2a2f22b test(chat): reject a valid signed profile stored with the wrong SQLite type 2026-10-27 07:31:16 +01:00
evgeny 9342795008 fix(chat): check stored text types before SQLite converts their values 2026-10-27 07:31:16 +01:00
evgeny fe5cf910e1 test(chat): cover preference read errors and all queued sound form values 2026-10-27 07:29:48 +01:00
evgeny 09e3ba62ef test(chat): verify preference rollback, committed sound delivery, and request validation 2026-10-27 07:27:44 +01:00
evgeny fdb0381f5c fix(gui): retain sound preference keys until the queued request is copied 2026-10-27 07:25:26 +01:00
evgeny 81fdbf90e1 fix(chat): skip initial sound publication when preference reading fails 2026-10-27 07:25:26 +01:00
evgeny fec2cecdb3 fix(chat): commit UI preferences before reporting or broadcasting them 2026-10-27 07:24:30 +01:00
evgeny 5360453960 test(chat): reproduce committed UI state after a finalization error 2026-10-27 07:22:45 +01:00
evgeny 34e729d988 docs(chat): record owner editor fault matrix and cross-platform validation 2026-10-27 07:21:26 +01:00
evgeny 11135283e7 docs(chat): document canonical owner versions and atomic editor behavior 2026-10-27 07:17:23 +01:00
evgeny c8e1d120ba fix(android): include the owner block size contract for role parsing 2026-10-27 07:16:37 +01:00
evgeny 104b702653 test(chat): inject owner editor allocation failures before commit 2026-10-27 07:15:15 +01:00
evgeny be311cf144 test(chat): include the member display contract explicitly 2026-10-27 07:13:41 +01:00
evgeny 9e10f7a357 test(chat): cover long role histories and deletion from owner commit callbacks 2026-10-27 07:13:19 +01:00
evgeny 6224c017da fix(chat): reject truncated or malformed stored owner JSON before comparison 2026-10-27 07:13:19 +01:00
evgeny a14fdf6d83 test(chat): cover owner edit conflicts, retry isolation, histories, and GUI patches 2026-10-27 07:12:13 +01:00
evgeny 98741e47d8 docs(chat): define owner editor conflict, history, and patch contracts 2026-10-27 07:09:50 +01:00
evgeny e3ea2ef78f fix(chat): preserve unedited GUI tags and read complete role histories 2026-10-27 07:08:33 +01:00
evgeny b7f799ebe5 test(chat): target the complete owner snapshot query 2026-10-27 07:07:30 +01:00
evgeny cde8c7b8e5 fix(chat): commit owner edits against a locked baseline and retain retry state 2026-10-27 07:06:09 +01:00
evgeny a9618169ab fix(chat): load complete verified owner snapshots and validate editor input 2026-10-27 07:04:28 +01:00
evgeny 16d7fc4fb5 fix(chat): validate owner versions and complete member reads before mutation 2026-10-27 07:02:44 +01:00
evgeny 91fb996a09 test(chat): reproduce owner editor load after SQL finalization error 2026-10-27 07:02:03 +01:00
evgeny f0d864bfd9 docs(chat): record profile full suite and sanitizer fixture correction 2026-10-27 07:00:13 +01:00
evgeny 59d8065fae test(chat): clear borrowed fault selector before its scope ends 2026-10-27 06:58:14 +01:00
evgeny 247952e9ed docs(chat): record signed profile transactions and callback fault coverage 2026-10-27 06:56:56 +01:00
evgeny 8bf09d9513 docs(sqlite): clarify verified node and owner write failures 2026-10-27 06:55:54 +01:00
evgeny f66c4e928e fix(member-files): preserve the original lookup error in ACL diagnostics 2026-10-27 06:50:02 +01:00
evgeny cce633b5b0 test(chat): reject negative owner results before checking change flags 2026-10-27 06:48:29 +01:00
evgeny beac8afba8 test(chat): cover profile trust, owner rollback, avatar policy, and startup failure 2026-10-27 06:46:15 +01:00
evgeny ecb589c670 test(chat): exercise atomic profile updates, no-ops, and callback deletion 2026-10-27 06:42:32 +01:00
evgeny ebb89e1bc3 test(chat): add profile transaction faults and committed notification observer 2026-10-27 06:39:57 +01:00
evgeny 70a4c669dc test(chat): verify nested member callback cancellation and namespace lifetime 2026-10-27 06:37:09 +01:00
evgeny f1d80922c7 fix(chat): fail startup when the JOIN apply subscription cannot be installed 2026-10-27 06:35:37 +01:00
evgeny 64adb799e9 fix(chat): retain member notification data across callback cancellation 2026-10-27 06:35:37 +01:00
evgeny 6efe3000d0 fix(chat): verify existing JOIN before signing local profile updates 2026-10-27 06:27:01 +01:00
evgeny 3195167ff3 fix(chat): commit signed profile updates under one version lock 2026-10-27 06:23:48 +01:00
evgeny 1cc60a3079 fix(json): decode Unicode escapes without losing subsequent profile fields 2026-10-27 06:21:05 +01:00
evgeny 20c095f2f3 fix(chat): preserve member transaction boundaries when rollback fails 2026-10-27 06:15:20 +01:00
evgeny b52e5f5489 fix(chat): validate complete signed profile before publishing read output 2026-10-27 06:13:12 +01:00
evgeny 30d58a4bde test(chat): reproduce successful signed profile read after finalization error 2026-10-27 06:12:04 +01:00
evgeny 1843a492bc docs(chat): record full JSON export validation 2026-10-27 06:07:29 +01:00
evgeny 463041a87f docs(chat): describe complete JSON exports and listing failure tests 2026-10-27 06:06:55 +01:00
evgeny cb0b71aec1 test(chat): roundtrip every ASCII control byte in channel JSON 2026-10-27 06:00:15 +01:00
evgeny f5270db52b test(chat): verify lossless JSON, corrupted rows, and deferred channel visibility 2026-10-27 05:58:08 +01:00
evgeny 92317bf383 test(chat): add JSON SQL faults and exact-capacity contract checks 2026-10-27 05:56:46 +01:00
evgeny 29e15254a1 fix(chat): reject truncated SQLite text in exported JSON 2026-10-27 05:53:11 +01:00
evgeny d5070a5df6 fix(chat): return complete escaped JSON and propagate listing SQL failures 2026-10-27 05:51:26 +01:00
evgeny 5fe66585b6 test(chat): reproduce invalid JSON for a signed channel name 2026-10-27 05:49:58 +01:00
evgeny 774fb66bb9 docs(chat): record full member and diagnostics validation 2026-10-27 05:46:06 +01:00
evgeny cfe4c24584 docs(chat): record member, mute, and diagnostics audit evidence 2026-10-27 05:42:28 +01:00
evgeny cec3e27aab test(chat): make diagnostic name expectation explicit in member fixture 2026-10-27 05:40:10 +01:00
evgeny 5af4572ae1 test(chat): verify invalid requests and diagnostic name lookup failures 2026-10-27 05:39:05 +01:00
evgeny 618c68268c docs(chat): specify complete member snapshots and committed local mute 2026-10-27 05:38:07 +01:00
evgeny 41b3503398 fix(chat): bound diagnostic counters and invalid mute request parsing 2026-10-27 05:37:05 +01:00
evgeny fd4c13f219 test(chat): give diagnostic links a valid empty ACK queue 2026-10-27 05:35:27 +01:00
evgeny a9bc410aad test(chat): include complete ETCP types for diagnostic fixture 2026-10-27 05:34:32 +01:00
evgeny 7279967a29 test(chat): cover member limits, radio commits, and large diagnostics 2026-10-27 05:33:33 +01:00
evgeny 8de9cfb1d2 fix(chat): build complete diagnostics with checked buffers and SQL results 2026-10-27 05:31:19 +01:00
evgeny 2504dd0b40 test(chat): add member SQL and committed radio state observers 2026-10-27 05:29:34 +01:00
evgeny 1bb824fb8a fix(chat): commit radio mute before applying cache and reporting success 2026-10-27 05:24:47 +01:00
evgeny 32a8c1c48b fix(chat): publish complete member snapshots after checked SQL finalization 2026-10-27 05:23:17 +01:00
evgeny 958feb4e75 test(chat): reproduce successful member snapshot after finalization failure 2026-10-27 05:22:09 +01:00
evgeny d3c5565c91 docs(chat): record full avatar suite and sanitizer results 2026-10-27 05:20:30 +01:00
evgeny 63c92840e2 docs(chat): mark avatar audit fixes complete with targeted verification 2026-10-27 05:19:14 +01:00
evgeny 32c89c7110 docs(chat): record avatar failure reproduction and transaction validation 2026-10-27 05:16:43 +01:00
evgeny ae74b621c8 docs(chat): specify avatar transaction, failure, and callback lifetime contracts 2026-10-27 05:15:12 +01:00
evgeny 2c691f98f7 test(chat): include EVP declarations explicitly in avatar SQL fixture 2026-10-27 05:13:08 +01:00
evgeny e8b913a351 test(chat): cancel avatar peers from the committed receive callback 2026-10-27 05:12:49 +01:00
evgeny 65409f8c80 test(chat): exercise avatar transaction, schema, and key lookup failures 2026-10-27 05:12:35 +01:00
evgeny 8b16f40094 test(chat): add precise avatar SQL fault hooks and committed-state observer 2026-10-27 05:11:03 +01:00
evgeny e645ef309a fix(member-files): reject membership lookup binding and finalization errors 2026-10-27 05:09:44 +01:00
evgeny e0598ccc22 fix(chat): commit avatar updates before notification and validate SQL reads 2026-10-27 05:08:31 +01:00
evgeny bc41bb68b6 test(chat): reproduce successful avatar publication after failed hash binding 2026-10-27 05:05:40 +01:00
evgeny f378c7b28d docs(chat): record full channel creation validation 2026-10-27 05:04:46 +01:00
evgeny 04ce61e3ca docs(chat): describe atomic channel creation and verified failure paths 2026-10-27 05:02:28 +01:00
evgeny 8003413d97 test(chat): cover channel input contracts and TCP creation result 2026-10-27 05:00:27 +01:00
evgeny f1cada4c02 Cover channel crypto failures and require owner close after failed rollback 2026-10-27 04:49:39 +01:00
evgeny 01c2ebd7d8 Verify channel SQL failure rollback and complete signed profiles through an independent reader 2026-10-27 04:43:31 +01:00
evgeny 1d84765f08 Instrument channel creation SQL and hash committed schema, identities and roots 2026-10-27 04:40:36 +01:00
evgeny 60942e542b Propagate all member block binding and finalization failures before index publication 2026-10-27 04:36:09 +01:00
evgeny 1ce58cbeac Reject publication when the initial member profile signature cannot be bound 2026-10-27 04:34:57 +01:00
evgeny 956febe1d7 Report committed channel creation results through the headless API 2026-10-27 04:27:31 +01:00
evgeny 129fece0af Share channel description verification with JOIN and cleanse owned creation requests 2026-10-27 04:27:31 +01:00
evgeny 55e270898b Check channel key generation and return the committed channel identity 2026-10-27 04:26:43 +01:00
evgeny 72b3068a8b Commit new channel identity and signed root membership before runtime publication 2026-10-27 04:25:08 +01:00
evgeny c0aacb3287 Define one bounded channel description encoding for signing and verification 2026-10-27 04:23:22 +01:00
evgeny 6a6ad5c612 Store channel metadata and peer schema atomically with checked SQL operations 2026-10-27 04:19:14 +01:00
evgeny 999fe909e4 Target the exact signed JOIN body instead of counting unrelated signatures 2026-10-27 04:16:07 +01:00
evgeny a4dd4a10d5 Exercise failed root signing during channel creation against committed SQLite 2026-10-27 04:12:58 +01:00
evgeny 1c5faaffc3 Record full feedback and poll verification after moving sanitizer artifacts 2026-10-27 04:06:52 +01:00
evgeny 9b55e3c7cb Record verified feedback rollback and poll command readback contracts 2026-10-27 04:02:56 +01:00
evgeny 6c0f9c9068 Reject embedded NUL before passing animation JSON to rlottie 2026-10-27 04:00:54 +01:00
evgeny 1b0034e1ba Handle saved-setting apply errors and document committed CLI interaction results 2026-10-27 03:58:19 +01:00
evgeny a7a7e4b5a1 Cancel member actions when a click becomes a drag 2026-10-27 03:54:03 +01:00
evgeny d741eb7374 Document feedback transaction ownership, codecs and committed readback acknowledgments 2026-10-27 03:52:09 +01:00
evgeny 7f0845e50c Check readback retries and refused acknowledgments keep feedback roots unchanged 2026-10-27 03:50:16 +01:00
evgeny 739ee0802f Verify poll commit acknowledgments survive snapshot faults and reserve memory before changes 2026-10-27 03:49:38 +01:00
evgeny 9876677a5f Refresh committed feedback without repeating user actions after readback errors 2026-10-27 03:49:38 +01:00
evgeny 1666538b0c Acknowledge committed poll commands when snapshot readback fails 2026-10-27 03:49:09 +01:00
evgeny 70251fafab Verify poll SQL failures preserve history, reactions, roots and events 2026-10-27 03:45:11 +01:00
evgeny 63e76d2cf5 Add targeted SQL read fault injection for poll command tests 2026-10-27 03:44:02 +01:00
evgeny 1820128f5b Document member badge painting and ignored state flags 2026-10-27 03:43:31 +01:00
evgeny efe879bfd9 Preserve complete audio frames and reject invalid ring buffers 2026-10-27 03:42:03 +01:00
evgeny aef6aae432 Validate complete poll command reads before publication or reaction changes 2026-10-27 03:41:36 +01:00
evgeny cf7a3a0939 Check SQL reads before interpreting poll targets and command fields 2026-10-27 03:41:06 +01:00
evgeny d89a86c9dd Cover feedback page and hash SQL errors without empty success 2026-10-27 03:38:21 +01:00
evgeny 7fa20ceb79 Specify shared FFmpeg image buffer ownership 2026-10-27 03:38:12 +01:00
evgeny 96a3d05c74 Reject failed feedback page and hash reads and report transaction error codes 2026-10-27 03:37:29 +01:00
evgeny fc94fa0bfd Own feedback version selection and page publication transactions 2026-10-27 03:35:03 +01:00
evgeny b0acb285c1 Bound TGS decoding and keep invalid icons out of animation 2026-10-27 03:33:50 +01:00
evgeny a591469770 Check feedback lookups and writes and retain rollback ownership 2026-10-27 03:33:34 +01:00
evgeny 1f19720cb8 Exercise feedback lookup failures, atomic retries and rollback ownership 2026-10-27 03:32:32 +01:00
evgeny 6a4fa8065a Add targeted SQL failure injection to real signed feedback tests 2026-10-27 03:30:51 +01:00
evgeny 1e5fc2d335 Record full 213-test verification and diagnose SQL clock fixture failure 2026-10-27 03:28:40 +01:00
evgeny 3309bee7eb Compare attachment SQL timestamps using the SQLite clock 2026-10-27 03:24:22 +01:00
evgeny 41ce04e2f0 Document desktop instance activation and lock lifetime 2026-10-27 03:22:21 +01:00
evgeny 795f930dd6 Record attachment index recovery and immutable settings verification 2026-10-27 03:22:19 +01:00
evgeny 55328e18af Clarify LAN adapter thread, delivery and settings contracts 2026-10-27 03:20:41 +01:00
evgeny 8fefd510a6 Document committed outbox retries and transaction-safe preparation recovery 2026-10-27 03:20:41 +01:00
evgeny dafd3a2adc Reject malformed audio diagnostic snapshots 2026-10-27 03:19:03 +01:00
evgeny 0995a1eac3 Complete event diagnostics and clarify attachment event payloads 2026-10-27 03:17:05 +01:00
evgeny 40ae782719 Cover settings immutability, validation rollback and LAN apply retry 2026-10-27 03:15:58 +01:00
evgeny 43f9608fbf Make chat settings reads immutable and validation failures atomic 2026-10-27 03:15:15 +01:00
evgeny 27aa76f914 Match recovery fixture byte count and normal cached-file policy 2026-10-27 03:14:09 +01:00
evgeny 9fa58b4f83 Keep desktop config projection separate from core settings 2026-10-27 03:14:00 +01:00
evgeny f6f3ca8da7 Share checked desktop config batches and diagnose write failures 2026-10-27 03:14:00 +01:00
evgeny bc11c6ac00 Check attachment initialization leaves an external transaction untouched 2026-10-27 03:12:56 +01:00
evgeny 52d8ec4e49 Preserve attachment files when shutdown sees an open transaction 2026-10-27 03:12:37 +01:00
evgeny 6bbd41f49f Exercise attachment recovery against uncommitted history deletion 2026-10-27 03:12:11 +01:00
evgeny 7f8869537b End idle attachment outbox scans without invoking commit hooks 2026-10-27 03:06:26 +01:00
evgeny 108266328c Commit attachment retry reservations before network delivery 2026-10-27 03:00:30 +01:00
evgeny b9d36b42af Report manifest limits and active download refusals precisely 2026-10-27 02:59:02 +01:00
evgeny 59d51d0e80 Document atomic attachment indexes and signed-history recovery 2026-10-27 02:58:44 +01:00
evgeny 13918d1cea Preserve desktop configuration on failed writes 2026-10-27 02:57:07 +01:00
evgeny 00c4065771 Use the signed-history limit for manual attachment parsing 2026-10-27 02:50:27 +01:00
evgeny 61ed80e18c Share the ETCP monitor across desktop entry points 2026-10-27 02:49:39 +01:00
evgeny 67368ebbac Check complete signed manifests beyond the old manual download limit 2026-10-27 02:46:59 +01:00
evgeny 2165c8a1f8 Exercise real manifest recovery and bounded backfill overflow 2026-10-27 02:38:02 +01:00
evgeny 7e7cabfb3a Verify atomic manifest indexes, local intent and history recovery 2026-10-27 02:34:02 +01:00
evgeny 78d0e3f54f Retry failed decryption after a newly verified download 2026-10-27 02:31:29 +01:00
evgeny b31f974a44 Target local attachment transactions and observe recovery timers in tests 2026-10-27 02:28:42 +01:00
evgeny 1b695fe247 Own and cancel desktop bridge commands before core teardown 2026-10-27 02:25:05 +01:00
evgeny fdb11ed3ce Restore retained attachment indexes during startup and manual download 2026-10-27 02:20:02 +01:00
evgeny d9f5da130e Recover attachment indexes from history without losing message events 2026-10-27 02:18:30 +01:00
evgeny fc60ca295a Commit attachment download intent and cache restoration atomically 2026-10-27 02:16:23 +01:00
evgeny 45d5aaa7a1 Index attachment manifests atomically and classify invalid identities 2026-10-27 02:15:14 +01:00
evgeny fe75a493ef Commit immutable attachment identity before message publication 2026-10-27 02:09:17 +01:00
evgeny 6803369a13 Record verified outgoing, completion and channel deletion fixes 2026-10-27 02:05:25 +01:00
evgeny 618f6ca073 Document atomic channel deletion and post-commit file cleanup 2026-10-27 01:55:35 +01:00
evgeny c3ac2059f4 Check complete Merkle cleanup before committing channel deletion 2026-10-27 01:55:03 +01:00
evgeny 8850121984 Verify channel deletion rollback and committed cascade snapshots 2026-10-27 01:53:47 +01:00
evgeny 6a6f8db208 Preserve channel files until checked metadata deletion commits 2026-10-27 01:50:03 +01:00
evgeny cd6ca2388f Cascade attachment records with channel deletion before cleaning files 2026-10-27 01:50:02 +01:00
evgeny 34e6fecbd0 Target completion transaction faults without affecting history jobs 2026-10-27 01:49:03 +01:00
evgeny 75124e0efa Preserve independent NAT details in desktop diagnostics 2026-10-27 01:48:13 +01:00
evgeny 12c5945eed Handle unavailable cores and late status page responses 2026-10-27 01:44:40 +01:00
evgeny 77e0a3c93e Verify completion ownership through cancellation, retry and task limits 2026-10-27 01:43:50 +01:00
evgeny b2addca5ce Clarify desktop logging contracts and retain early log path 2026-10-27 01:41:23 +01:00
evgeny d22bae19b4 Fix desktop node startup rollback and state ownership 2026-10-27 01:38:26 +01:00
evgeny d7ffa1031f Exercise committed decryption claims and retryable SQL completions 2026-10-27 01:37:30 +01:00
evgeny b71c3040d4 Claim decryption before workers and retry retained completions 2026-10-27 01:35:30 +01:00
evgeny 4d19de7cce Retain attachment completions until their SQL result commits 2026-10-27 01:34:47 +01:00
evgeny 851c6723ff Verify outgoing request persistence and document commit boundary 2026-10-27 01:30:24 +01:00
evgeny d1bfd1d16c Commit outgoing attachment requests before events and delivery 2026-10-27 01:28:23 +01:00
evgeny 023bd78e16 Cover atomic outgoing attachment request creation and timer guard 2026-10-27 01:27:19 +01:00
evgeny b163642b52 Fix oversized ETCP monitor snapshots 2026-10-27 01:26:16 +01:00
evgeny 8a0654e57b Merge remote-tracking branch 'origin/master' 2026-10-27 01:23:25 +01:00
evgeny e43bcec7cb Record verified REQUEST commit fix and continue chat audit 2026-10-27 01:22:57 +01:00
evgeny 383eb6d076 Describe atomic REQUEST acceptance and committed acknowledgment tests 2026-10-27 01:17:40 +01:00
evgeny bb961dd394 Exercise rejected REQUEST, author restart and real retry before ACK 2026-10-27 01:12:11 +01:00
evgeny 4d87cab28a docs(dm): align history generation contract after rebase 2026-10-27 01:11:28 +01:00
evgeny 5bb27d1b61 docs(dm): record completed contract audit and validation 2026-10-27 01:06:45 +01:00
evgeny 9480f8029b docs(dm): finish invite and cleanup validation contracts 2026-10-27 01:06:45 +01:00
evgeny a00db6229f docs(dm): reconcile architecture and PM delivery requirements 2026-10-27 01:06:45 +01:00
evgeny ad577318d9 docs(dm): specify media protocol and worker lifetime 2026-10-27 01:06:45 +01:00
evgeny 1cfafc43a4 docs(dm): complete mailbox and storage coordinator contracts 2026-10-27 01:06:45 +01:00
evgeny 2fe024fbbb docs(dm): clarify core and history ownership contracts 2026-10-27 01:06:45 +01:00
evgeny 98a6d3cce0 Test committed REQUEST acknowledgments, duplicates and SQL failures 2026-10-27 01:05:49 +01:00
evgeny 760398b96c Commit incoming attachment requests before acknowledging them 2026-10-27 01:02:55 +01:00
evgeny 492f6adc99 Merge upstream attachment audit documentation 2026-10-27 00:57:14 +01:00
evgeny 102da344d9 Merge origin/master with Android conversation gestures 2026-10-27 00:55:47 +01:00
evgeny 15ec41f2fd Record lost REQUEST after real acknowledgment and author rollback 2026-10-27 00:55:14 +01:00
evgeny 9f7ceb5815 Document REQUEST acknowledgment before external transaction commit 2026-10-27 00:55:13 +01:00
evgeny 13039933da android: separate avatar taps from conversation context menus 2026-10-27 00:49:00 +01:00
evgeny ef8e8f2cb5 Record verified author decision fix and close its audit task 2026-10-27 00:45:43 +01:00
evgeny 7649981cbc Describe committed author decisions and rollback lifecycle 2026-10-27 00:39:18 +01:00
evgeny 401193950b Verify author decision rollback and retry across real chat restart 2026-10-27 00:15:17 +01:00
evgeny 8c36d00fd2 Test atomic attachment decisions and committed UI notifications 2026-10-27 00:13:31 +01:00
evgeny 8a7f4469dc Commit author attachment decisions and delivery queue atomically 2026-10-27 00:10:58 +01:00
evgeny 77d6e8cfd0 Record reproduced attachment decision durability failures 2026-10-26 23:50:40 +01:00
evgeny 55ad0e971a Document uncommitted or undeliverable attachment author decisions 2026-10-26 23:49:35 +01:00
evgeny e6c0271e2c Record validated chat merge and stop the audit after Pull 2026-10-26 23:41:43 +01:00
evgeny 845bf2580d Merge upstream chat revisions with attachment transaction fixes 2026-10-26 23:35:21 +01:00
evgeny 012bd650ea Record verified GRANT fix before integrating upstream chat revisions 2026-10-26 23:22:57 +01:00
evgeny b8b6636644 Document result commit guarantees and verify quiesced callback removal 2026-10-26 23:17:55 +01:00
evgeny 9839f56f8c Exercise real GRANT retry and verify committed key before network ACK 2026-10-26 23:09:49 +01:00
evgeny 03d1afbd13 Tighten result regression snapshots and expose SQL transition diagnostics 2026-10-26 23:07:50 +01:00
evgeny 935bd704ae Test attachment result transaction failures and committed acknowledgments 2026-10-26 23:06:20 +01:00
evgeny 54a6e33c5e Commit attachment result state and key before acknowledging delivery 2026-10-26 23:03:19 +01:00
evgeny ab0b866c4c Explain edit rejection causes and unchanged submissions in diagnostics 2026-10-26 22:59:26 +01:00
evgeny 4b189891f7 Keep UI test references stable across queued channel refreshes 2026-10-26 22:58:15 +01:00
evgeny 5cf823da6a Record real-network GRANT bind failure and stop attachment audit 2026-10-26 22:57:20 +01:00
evgeny 334991fbe5 Initialize the desktop edit fixture with a valid test identity 2026-10-26 22:56:21 +01:00
evgeny 52651cfa0d Document confirmed GRANT acknowledgment without saved attachment key 2026-10-26 22:55:49 +01:00
evgeny 87f312f31b Retain startup diagnostics for the desktop edit integration test 2026-10-26 22:55:05 +01:00
evgeny b19e6797c9 Preserve Android edit drafts across screen recreation and serialize saves 2026-10-26 22:54:36 +01:00
evgeny e229811e20 Document editable history protocol and update media insert callback 2026-10-26 22:54:25 +01:00
evgeny aefef51c58 Update stress and media fixtures to sign versioned group records 2026-10-26 22:52:35 +01:00
evgeny 45257bf37f Exercise desktop editing through the real menu composer core and quoted replies 2026-10-26 22:51:10 +01:00
evgeny d998b390f3 Exercise offline and live edits over real Merkle and PUSH transport 2026-10-26 22:50:20 +01:00
evgeny ec8c6e9eb1 Verify edit events bypass new-message callbacks and notifications 2026-10-26 22:49:45 +01:00
evgeny 8523448c3a Reserve desktop edit dispatch and reject malformed update events 2026-10-26 22:49:45 +01:00
evgeny 5b6c96d3d8 Test desktop composer edit confirmation cancel failure and channel changes 2026-10-26 22:47:58 +01:00
evgeny 48bdb85ff9 Preserve composer media policy and display edit times for short or emoji text 2026-10-26 22:47:57 +01:00
evgeny 8b34889a19 Check signed reply references against the revision envelope 2026-10-26 22:46:42 +01:00
evgeny e45f33e7b5 Cover revision conflicts Merkle updates stale ACKs and rollback 2026-10-26 22:46:08 +01:00
evgeny 82ef6f282f Reset only dependent group history state when adopting editable format 2026-10-26 22:46:08 +01:00
evgeny 0a75a53ed9 Correct Android attachment submission argument after editor integration 2026-10-26 22:45:04 +01:00
evgeny c39bdef344 Localize group editing controls and edit timestamps 2026-10-26 22:45:04 +01:00
evgeny 030336eaeb Record verified attachment key fix lifecycle contracts and validation 2026-10-26 22:44:14 +01:00
evgeny d0ff7a81f7 Bind deferred-author integrity fixture to its signed author 2026-10-26 22:43:46 +01:00
evgeny 65cdb5b468 Keep format-reset rollback safe and expire pending revisions by edit time 2026-10-26 22:43:38 +01:00
evgeny cad10a33e0 Test group edit persistence references and scoped dev format reset 2026-10-26 22:42:36 +01:00
evgeny 93057c9eb7 Adapt signed history regression fixtures to canonical revision envelopes 2026-10-26 22:41:56 +01:00
evgeny 1afb1010cc Wire desktop context-menu editing and update visible messages in place 2026-10-26 22:38:42 +01:00
evgeny 2a9b5748e9 Show edited time and retain revision metadata in desktop rows 2026-10-26 22:38:17 +01:00
evgeny 20350338b8 Deliver committed edits to desktop without message notifications 2026-10-26 22:38:17 +01:00
evgeny e483027e3e Edit group text in desktop composer with save cancel and draft restoration 2026-10-26 22:38:06 +01:00
evgeny b46927f40d Read group revisions and keep history windows ordered by stable IDs 2026-10-26 22:37:39 +01:00
evgeny 371aa3ac19 Dispatch correlated edit submissions through shared composer request 2026-10-26 22:37:39 +01:00
evgeny ca15dbb88a Save authored text edits and preserve group references across revisions 2026-10-26 22:36:47 +01:00
evgeny 2f35502978 Expose group message editing and committed update event 2026-10-26 22:35:46 +01:00
evgeny 809f009796 Replicate group message revisions atomically with versioned acknowledgements 2026-10-26 22:35:34 +01:00
evgeny 5c638a60db Define permanent group message identity from creation fields 2026-10-26 22:33:43 +01:00
evgeny b0d246913d Complete Android navigation after PM conversation deletion 2026-10-26 22:11:39 +01:00
evgeny 18df7cc43d Describe media backfill triggers in terms of Merkle history sync 2026-10-26 22:11:39 +01:00
evgeny 9009153cc5 Remove unused legacy chat sync commands and empty connect API 2026-10-26 22:11:39 +01:00
evgeny 5dab86e840 Initialize chat schema before storing and publishing local identity 2026-10-26 22:11:39 +01:00
evgeny f6005fd96d Remove obsolete history chain reads from chat caches and API 2026-10-26 22:11:39 +01:00
evgeny f1da7d7ee8 Align desktop history reads with Merkle schema and fix PM test setup 2026-10-26 22:11:39 +01:00
evgeny cd0329b301 Cover deleted PM composer state and log GUI deletion failures 2026-10-26 22:11:39 +01:00
evgeny 8ccad3b56b Test PM deletion through the desktop window and history snapshot generations 2026-10-26 22:11:39 +01:00
evgeny e88f3ce46a Finish PM composer cleanup and skip history requests after shutdown 2026-10-26 22:11:39 +01:00
evgeny f83033d3a1 Guard Android PM history and pending deletion across asynchronous sends 2026-10-26 22:11:39 +01:00
evgeny 5778c8aa0a Translate desktop PM deletion confirmation and errors 2026-10-26 22:11:39 +01:00
evgeny 6382c794ea Complete desktop PM deletion after the core transaction result 2026-10-26 22:11:39 +01:00
evgeny 4089944673 Guard desktop PM sends and history by conversation generation 2026-10-26 22:11:39 +01:00
evgeny e10354a0ac Keep PM composer work bound to its history generation 2026-10-26 22:11:39 +01:00
evgeny df80c43a57 Offer conversation deletion in the desktop PM context menu 2026-10-26 22:11:39 +01:00
evgeny 8e3c536cbb Bridge desktop DM deletion requests and results 2026-10-26 22:11:39 +01:00
evgeny f0b7b22f92 Read visible DM generations in the desktop conversation list 2026-10-26 22:11:39 +01:00
evgeny fd82e7bf1b Tag DM history snapshots with conversation generation 2026-10-26 22:11:39 +01:00
evgeny 71dfc9d70d Clarify attachment commit ownership and SQL failure diagnostics 2026-10-26 22:10:44 +01:00
evgeny e5ca2e174c Honor core stop before and after Android restart with lifecycle regressions 2026-10-26 22:07:39 +01:00
evgeny c75bfc618a Honor core stop in desktop owner loop and verify cleanup 2026-10-26 22:07:39 +01:00
evgeny 07f63c3047 Document audited call video and session contracts 2026-10-26 21:54:18 +01:00
evgeny 289b592598 Use distinct regression helper name and reserved uasync post API 2026-10-26 21:53:36 +01:00
evgeny 99ebee37e7 Test attachment key commit faults ownership and retry with real workers 2026-10-26 21:51:36 +01:00
evgeny 549cc202fb Commit complete attachment preparation before accepting encryption work 2026-10-26 21:49:11 +01:00
evgeny d877e8881c Record confirmed attachment key bind failure and pause chat audit 2026-10-26 21:31:00 +01:00
evgeny e33d51a34a Document attachment key persistence failure during chat audit 2026-10-26 21:29:41 +01:00
evgeny 1899b7f8cf Record verified admin and worker rebase integration 2026-10-26 20:54:08 +01:00
evgeny 589fef2aae Reconcile audit contracts with upstream post cancellation 2026-10-26 20:48:15 +01:00
evgeny 8718ee901c Record verified worker shutdown fix and negative control 2026-10-26 20:46:31 +01:00
evgeny 2c48a53c6a Clarify cancellation ownership during service shutdown 2026-10-26 20:46:31 +01:00
evgeny 9e68928222 Test worker drain with completions in a detached batch 2026-10-26 20:45:32 +01:00
evgeny 781d41e003 Disable detached worker completions before draining jobs 2026-10-26 20:45:32 +01:00
evgeny 8f3d9edf8b Record admin verification and worker completion crash 2026-10-26 20:44:42 +01:00
evgeny 998993997d Diagnose admin key derivation failures without exposing secrets 2026-10-26 20:44:42 +01:00
evgeny 5169ffd0b3 Specify admin import transaction and notification contracts 2026-10-26 20:44:42 +01:00
evgeny cc04f1c0fa Test admin import rollback, commit notification and safe retry 2026-10-26 20:44:42 +01:00
evgeny 76527de44f Store admin keys atomically and reject invalid transfer context 2026-10-26 20:44:42 +01:00
evgeny e65ceeafdc Track atomic admin import correction and regression requirements 2026-10-26 20:44:42 +01:00
evgeny 1916ba4270 Document admin key import failures and null transfer crash 2026-10-26 20:44:42 +01:00
evgeny bc623f2371 docs(call): record post-rebase validation results 2026-10-26 20:30:18 +01:00
evgeny f521bb37f4 fix(call): align audio frontend ownership with core lifecycle
Keep the borrowed audio provider on UTUN_INSTANCE across chat service restarts.
Attach and detach Android voice from the core worker and reject DSP startup
after detach. Preserve TX owner epochs, pending slots and foreign-instance RX
isolation. Remove the unused cross-thread online API and keep its check local
to call.c.

Add eight lifecycle regressions with real cores and the Android host bridge.
Audit public call, DSP, clock, headless and desktop audio contracts and record
the findings and validation scope.

Validation: voice/desktop 38/38, four native call suites, native and both Android
ABI builds, full check 204/204 plus proxy/burst/load. JVM results remain Gradle
UP-TO-DATE (155 app and 15 router). No hardware runtime validation.
2026-10-26 20:22:46 +01:00
evgeny b84a6ab3b9 docs(call): record validated Bluetooth lifecycle fix and regressions 2026-10-26 20:22:27 +01:00
evgeny 2e8885548b docs(call): clarify Android output and Bluetooth proxy ownership 2026-10-26 20:21:58 +01:00
evgeny 83df895532 build(android): run router lifecycle regressions with app unit tests 2026-10-26 20:21:58 +01:00
evgeny f724703156 test(android): cover Bluetooth router teardown and callback races 2026-10-26 20:21:58 +01:00
evgeny 34133e4f6f test(android): isolate router application and logging fixtures 2026-10-26 20:21:58 +01:00
evgeny 8cbadd821f test(android): model Bluetooth proxy ownership and device callbacks 2026-10-26 20:21:58 +01:00
evgeny 161422b2cd test(android): add isolated host context and clock fixtures 2026-10-26 20:21:58 +01:00
evgeny de83d7bbf4 fix(android): own Bluetooth proxies across router lifecycle 2026-10-26 20:21:58 +01:00
evgeny 3987295707 Report exact DM SQL prepare errors without duplicate step failures 2026-10-26 19:50:03 +01:00
evgeny 497792da73 Commit exact DM custody tombstones before acknowledging deletion 2026-10-26 19:45:51 +01:00
evgeny 3f195c058b Retain DM coordinator bodies when assignment scans fail 2026-10-26 19:42:00 +01:00
evgeny 2fce4641ec Exercise DM cleanup SQL failures and durable ACK retries 2026-10-26 19:39:04 +01:00
evgeny 8642b04e6d Cover worker teardown with completions in the active post batch 2026-10-26 19:15:32 +01:00
evgeny 93ec12226f Cancel pending posts from active dispatch batches 2026-10-26 19:12:37 +01:00
evgeny 28a5d0509f Expire DM test custody only after confirmed storage 2026-10-26 18:42:45 +01:00
evgeny 25a8b905fc Accept verified DM originals after storage expiry 2026-10-26 18:42:45 +01:00
evgeny ab8713d88f Record post-rebase sync validation on current master 2026-10-26 18:34:45 +01:00
evgeny c5075354d0 Record completed sync audit scope and refresh historical design links 2026-10-26 18:27:49 +01:00
evgeny 1456f02c03 Reconcile completed member and Merkle documentation audit status 2026-10-26 18:27:49 +01:00
evgeny b48f9e7a19 Close history Merkle migration with final validation results 2026-10-26 18:27:49 +01:00
evgeny 750ccf638d Verify history migration results and checkpoint revision races 2026-10-26 18:27:27 +01:00
evgeny bf94b240c8 Wake the lifecycle fixture after asserting standby restoration 2026-10-26 18:27:27 +01:00
evgeny 7d6197b5eb Restore requested activity after forced-active stream regression 2026-10-26 18:27:27 +01:00
evgeny d532fe062e Avoid recursive standby retries on allocation failure 2026-10-26 18:27:27 +01:00
evgeny f92077e601 Isolate stream wake state and require full roots in sync stress 2026-10-26 18:27:27 +01:00
evgeny e00d1f5212 Diagnose Merkle source profiles and identify both exchange endpoints 2026-10-26 18:27:27 +01:00
evgeny 669ad86e57 Document shared history Merkle protocol and bounded transactions 2026-10-26 18:27:26 +01:00
evgeny df39999624 Initialize media history model and admit the purge test peer 2026-10-26 18:27:26 +01:00
evgeny 316bacd8c8 Share isolated history model setup across sync fixtures 2026-10-26 18:27:26 +01:00
evgeny f42f002eb1 Test atomic page rollback, late author keys and model run policy 2026-10-26 18:27:26 +01:00
evgeny fefc0ee003 Preserve Android standby retry waits and clarify history contracts 2026-10-26 18:27:26 +01:00
evgeny 0444a4bfd9 Resume admitted history peers and gate automatic Merkle work by policy 2026-10-26 18:27:26 +01:00
evgeny a7b556d9a8 Verify long equal-count history divergence converges by full roots 2026-10-26 18:27:26 +01:00
evgeny 2833c53644 Cover handshake RNG failures and diagnose mismatched round tokens 2026-10-26 18:27:26 +01:00
evgeny a46091cb19 Yield the event loop between bounded history maintenance batches 2026-10-26 18:27:26 +01:00
evgeny 3a4143183d Cover stable history cursors, deleted authors and bounded TTL cleanup 2026-10-26 18:27:26 +01:00
evgeny 3fe697e1a9 Log history pause and await verified roots in empty peer fixtures 2026-10-26 18:27:26 +01:00
evgeny d76eb067bb Preserve signed history through schema conversion and resume both peers 2026-10-26 18:27:26 +01:00
evgeny 1402413ab9 Exercise history Merkle roots over live peers and invitation recovery 2026-10-26 18:27:26 +01:00
evgeny a87ece370c Revalidate history peers after membership and cover preflight integrity 2026-10-26 18:27:26 +01:00
evgeny 012cbdcd49 Register history after shared Merkle startup and validate page cursors 2026-10-26 18:27:26 +01:00
evgeny e822f9fef7 Pass leaf bounds to immediate page models and report disconnects 2026-10-26 18:27:26 +01:00
evgeny 5e5ed41c19 Replace history chain exchange with canonical Merkle data model 2026-10-26 18:27:26 +01:00
evgeny 41c2a77fe6 Expose per-model work policy and checkpoint results for history 2026-10-26 18:27:26 +01:00
evgeny a079381c0a Test cancelled Merkle rounds against the fresh responder challenge 2026-10-26 18:27:26 +01:00
evgeny 45c282e0b7 Bind Merkle rounds to fresh initiator and responder tokens 2026-10-26 18:27:26 +01:00
evgeny 137e30ec82 Require a fresh responder token when reattaching Merkle sessions 2026-10-26 18:27:26 +01:00
evgeny d20f31c165 Plan canonical history reconciliation on the shared Merkle engine 2026-10-26 18:27:26 +01:00
evgeny 5ae5fd066d Close history integrity fixes and record remaining sync audit scope 2026-10-26 18:27:26 +01:00
evgeny 143788cdcd Document verified history deletion and message-specific delivery 2026-10-26 18:26:58 +01:00
evgeny aa97e053cd Ensure SQLite allocation failures cannot authorize history deletion 2026-10-26 18:26:58 +01:00
evgeny 7853fb0fc6 Keep chain reads and delivery confirmation failures explicit 2026-10-26 18:26:58 +01:00
evgeny 557c98aeae Cover history preservation, corruption cleanup and exact delivery ACKs 2026-10-26 18:26:58 +01:00
evgeny fd53b443a0 Preserve history on verification errors and identify delivery ACKs 2026-10-26 18:26:58 +01:00
evgeny 26432be0e4 Point delivery audit finding to the failing SQL statement 2026-10-26 18:26:58 +01:00
evgeny 6734035734 Record db_sync verification data loss, deletion policy and delivery SQL defect 2026-10-26 18:26:58 +01:00
evgeny 068eddefd8 Flag db_sync data loss on verification errors and invalid duplicate input 2026-10-26 18:26:31 +01:00
evgeny b0bf27de61 Close DM expiry fix with fault restart and sanitizer evidence 2026-10-26 18:06:14 +01:00
evgeny 9fe4e834fe Describe DM expiry reconciliation and await restarted test link 2026-10-26 18:02:29 +01:00
evgeny 59e694bd83 Check all SQL results during DM storage release 2026-10-26 17:54:45 +01:00
evgeny 5788d2557b Test DM release rollback and expiry recovery after restart 2026-10-26 17:54:45 +01:00
evgeny cb08faae04 Reconcile DM storage expiry and release assignments atomically 2026-10-26 17:49:26 +01:00
evgeny dda4a780e3 Document unreconciled DM media expiry after SQL failure 2026-10-26 17:42:45 +01:00
evgeny 3dc5eb502d Record post-rebase DM validation 2026-10-26 17:31:42 +01:00
evgeny 87d24b722b Document verified DM name normalization and regressions 2026-10-26 17:27:18 +01:00
evgeny d09ed0316f Preserve UTF-8 boundaries in DM peer names 2026-10-26 17:27:18 +01:00
evgeny fa76447f53 Close Android mute fix with native Android and full-suite verification 2026-10-26 17:14:58 +01:00
evgeny 79b06846c6 Test Android bridge mute after real AEC and AGC across unmute 2026-10-26 17:14:18 +01:00
evgeny 000b28027c Preserve Android raw capture through AEC and apply mute before Opus 2026-10-26 17:14:18 +01:00
evgeny bdaff406be Forward Android frame mute through the native capture bridge 2026-10-26 17:14:18 +01:00
evgeny f83e27260d Record rebased DM verification and UTF-8 name truncation defect 2026-10-26 17:07:18 +01:00
evgeny b6588d0594 Preserve DM state on database failures and document contracts 2026-10-26 16:55:20 +01:00
evgeny 03be46c339 Record desktop voice checks and reproduce Android mute signal after AEC 2026-10-26 16:34:23 +01:00
evgeny 5fee00c451 Clarify desktop voice contracts and document Android mute ordering defect 2026-10-26 16:31:11 +01:00
evgeny 54a7522dd9 Record headless PCM framing fix and full regression results 2026-10-26 16:08:35 +01:00
evgeny 0ad80f3906 Clarify frame assembly and keep reference PCM arithmetic signed 2026-10-26 15:58:11 +01:00
evgeny 7c4e6f9972 Test complete headless frames across queue and short-write boundaries 2026-10-26 15:55:08 +01:00
evgeny 913ae531ec Queue complete headless PCM frames and account for overflow drops 2026-10-26 15:51:35 +01:00
evgeny ae9d3f0103 Record headless PCM backpressure framing failure and repair plan 2026-10-26 15:35:03 +01:00
evgeny 45834692a7 Document headless PCM framing defect and independent codec ownership 2026-10-26 15:33:11 +01:00
evgeny 03b050949c Close radio mesh regression with full merged-branch verification 2026-10-26 15:16:13 +01:00
evgeny bf4d14c46e Guard mesh gate node indices before matching endpoints 2026-10-26 15:09:35 +01:00
evgeny 1bc27aa2ca Verify radio mesh deduplication independently of arrival order 2026-10-26 15:08:08 +01:00
evgeny ec795b4764 Explain false radio mesh failure and preserve rebase audit 2026-10-26 15:01:59 +01:00
evgeny ff394c7a6a Preserve final mesh duplicate read outside diagnostic mode 2026-10-26 14:57:41 +01:00
evgeny 21af2e0f35 Observe late mesh packets within the running event loop 2026-10-26 14:57:41 +01:00
evgeny d943c0ddca Poll diagnostic mesh tail after the original loop stops 2026-10-26 14:57:41 +01:00
evgeny c2908a6c58 Trace radio mesh packet paths and original stop conditions 2026-10-26 14:57:41 +01:00
evgeny 5587c60603 Record successful proxy integration checks after TX fix 2026-10-26 14:57:41 +01:00
evgeny faaa5a835a Record repeated full-check failure in unrelated radio mesh test 2026-10-26 14:57:41 +01:00
evgeny 2429688382 Document call audio TX fix and independent radio mesh flake 2026-10-26 14:57:41 +01:00
evgeny f0df3d8848 Make stale TX regressions assert observable behavior first 2026-10-26 14:57:24 +01:00
evgeny bbc9f750c3 Cover call audio TX ownership across lifecycle transitions 2026-10-26 14:57:24 +01:00
evgeny e11eca93bb Isolate call audio TX tasks by instance binding epoch 2026-10-26 14:57:24 +01:00
evgeny 266406261a Validate call audio ownership plan against lifecycle boundaries 2026-10-26 14:57:24 +01:00
evgeny a38b1f1e0b Record call audio audit scope and unchanged implementation checks 2026-10-26 14:57:24 +01:00
evgeny 6f8164d7cd Record call audio rebind counter defect and ownership plan 2026-10-26 14:57:24 +01:00
evgeny a4d8637f45 Document stale call audio tasks corrupting pending accounting 2026-10-26 14:57:09 +01:00
evgeny ea3685d8f5 Record final call admission contract and environment checks 2026-10-26 14:57:09 +01:00
evgeny c7387c2879 Record passing call admission and voice verification 2026-10-26 14:57:09 +01:00
evgeny 198cf52791 Document call admission fix and live regression coverage 2026-10-26 14:56:54 +01:00
evgeny 9838384d43 Authenticate admission fixture members for radio interaction 2026-10-26 14:56:54 +01:00
evgeny 56a06da35f Cover call admission, ID reuse and retained sessions on live cores 2026-10-26 14:56:54 +01:00
evgeny 96d99a183d Reject overlapping outgoing calls and registered call IDs 2026-10-26 14:56:54 +01:00
evgeny 7e69595372 Record call audit baseline checks and exact admission location 2026-10-26 14:56:54 +01:00
evgeny c5eb17e59b Record outgoing call admission defect and verification plan 2026-10-26 14:56:54 +01:00
evgeny aa09459c70 Document missing busy admission guard for outgoing calls 2026-10-26 14:56:06 +01:00
evgeny aea8ca7236 Close feedback admission fix with full integration and sanitizer verification 2026-10-26 14:44:03 +01:00
evgeny 1634499d84 Document active feedback, credential dependencies and permission round lifecycle 2026-10-26 14:44:03 +01:00
evgeny f3be00438b Assert profile updates leave feedback idle and preserve outer-commit change flags 2026-10-26 14:44:03 +01:00
evgeny 953e094c92 Restrict feedback invalidation to credential, key and admission changes 2026-10-26 14:44:03 +01:00
evgeny 5cae3d095d Keep the full-cursor comment beside its pagination test 2026-10-26 14:44:03 +01:00
evgeny c5a09c1413 Check permission round teardown, blocked error handoff and safe restart callbacks 2026-10-26 14:44:03 +01:00
evgeny 789e5663f7 End unauthorized feedback rounds while preserving watches for member restoration 2026-10-26 14:44:03 +01:00
evgeny 4278eb7851 Wait for incoming transport before late-peer group setup and check restored publishing 2026-10-26 14:44:03 +01:00
evgeny ea1c17593b Test full chat restart and late-peer convergence across member exclusion and restoration 2026-10-26 14:44:03 +01:00
evgeny bf941bfd14 Preserve precise author failure reasons and guard SQLite column allocation 2026-10-26 14:44:03 +01:00
evgeny 4b394b75e0 Cover feedback revocation, purge, delayed cross-channel credentials and transactional faults 2026-10-26 14:44:03 +01:00
evgeny 490b30b956 Update dependent feedback atomically with membership and filter poll results 2026-10-26 14:44:03 +01:00
evgeny 8925503d59 Retain inactive feedback while rebuilding and serving only verified active states 2026-10-26 14:44:03 +01:00
evgeny e7ae4025e2 Expose dataset registration for dependent model startup boundaries 2026-10-26 14:44:03 +01:00
evgeny 42808450b5 Distinguish member author admission, pending credentials and verification errors 2026-10-26 14:44:03 +01:00
evgeny 9c1b8e3e03 Record feedback plan dependency and cross-channel audit gaps 2026-10-26 14:44:03 +01:00
evgeny e1e9d63925 Record excluded-author feedback restart audit findings 2026-10-26 14:44:03 +01:00
evgeny 8e2036b435 Document feedback startup failure for excluded historical authors 2026-10-26 14:44:03 +01:00
evgeny e56790649a Record passing member purge integration and sanitizer validation 2026-10-26 14:44:02 +01:00
evgeny 16c64ca626 Describe Merkle index ownership and mark old sync plan historical 2026-10-26 14:42:59 +01:00
evgeny 26b6eca150 Clarify Merkle pull lifecycle, progress timeout and audit scope 2026-10-26 14:42:59 +01:00
evgeny 81712e74cd Document atomic member purge and verification error contracts 2026-10-26 14:42:59 +01:00
evgeny e4de937953 Use public READY checks in physical member purge regression 2026-10-26 14:42:59 +01:00
evgeny 8b525c06a9 Verify physical purge preserves radio and transport on rollback 2026-10-26 14:42:59 +01:00
evgeny fe182e4acc Check cleanup retries, request ownership and stream rollback 2026-10-26 14:42:59 +01:00
evgeny 87b22966b7 Exercise member cleanup transaction and verification failures 2026-10-26 14:42:59 +01:00
evgeny fbe3e7a279 Make member cleanup atomic and publish removals after commit 2026-10-26 14:42:59 +01:00
evgeny 1f3f1d9a34 Separate missing member verification keys from SQLite failures 2026-10-26 14:42:59 +01:00
evgeny fe7bcb334c Distinguish Ed25519 verification errors from invalid signatures 2026-10-26 14:42:59 +01:00
evgeny f79b9261c7 Record passing stream audit verification and remaining scope 2026-10-26 12:55:48 +01:00
evgeny 6689cf543b Clarify source signing key and interval estimate documentation 2026-10-26 12:54:52 +01:00
evgeny 409d9f3ca9 Record completed stream header audit and align native guide 2026-10-26 12:53:40 +01:00
evgeny de535e1713 Distinguish source mute state from immutable audio codec 2026-10-26 12:47:46 +01:00
evgeny 8533dfc303 Clarify asynchronous publisher and viewer session contracts 2026-10-26 12:45:31 +01:00
evgeny 0f54f5ef66 Specify stream playback clock and audio thread contracts 2026-10-26 12:43:25 +01:00
evgeny c5292c9994 Document stream member admission and wire codec contracts 2026-10-26 12:42:14 +01:00
evgeny 495972cfe6 Clarify stream ring and media cursor ownership and results 2026-10-26 12:40:44 +01:00
evgeny b25acce11b Specify stream queue accounting and timing metric snapshots 2026-10-26 12:33:15 +01:00
evgeny 080b14a51d Document stream flow lifetimes, leases and relay ownership 2026-10-26 12:31:01 +01:00
evgeny 5259c746d1 Record INFO expiry fix and complete IPv6-isolated verification 2026-10-26 12:19:42 +01:00
evgeny b116b20b11 Exercise INFO expiry under real ETCP backpressure 2026-10-26 12:04:31 +01:00
evgeny c148351259 Close expired nine-byte stream INFO requests with overload reason 2026-10-26 12:04:31 +01:00
evgeny 3956711c16 Record expired stream INFO probe defect and isolated evidence 2026-10-26 12:04:31 +01:00
evgeny 840bc9a6b0 Align stream guide with session ownership and current audit status 2026-10-26 12:04:31 +01:00
evgeny 27ed4c74ff Clarify stream session ownership and supplier selection contracts 2026-10-26 12:04:31 +01:00
evgeny 962a2df3f8 Add local channel deletion to desktop channel settings 2026-10-26 10:47:39 +01:00
evgeny d67e0b0c23 Report desktop startup failures and validate generated configs 2026-10-26 10:12:30 +01:00
evgeny 9ab9d01907 Fix Android config storage limits for the strict parser 2026-10-26 10:12:30 +01:00
evgeny 4abebdf35c Record passing stream publisher checks after integration 2026-10-26 09:58:45 +01:00
evgeny ced9dc2340 Merge remote-tracking branch 'origin/master' 2026-10-26 09:50:34 +01:00
evgeny 8627e4f6a5 Record stream packing fix and native regression coverage 2026-10-26 09:50:34 +01:00
evgeny a056b2c262 Describe publisher packing budgets and queued audio rejection 2026-10-26 09:50:34 +01:00
evgeny 017a326a13 Cover stream publisher packing boundaries and actor progress 2026-10-26 09:46:24 +01:00
evgeny 1a9fe0a33b Fix stream publisher audio packing and video progress 2026-10-26 09:44:16 +01:00
evgeny 8e74619501 Make chat joins atomic and test invitation lifecycle failures 2026-10-26 09:19:35 +01:00
evgeny bb6ed1723f Close instance audit with full integration and sanitizer results 2026-10-26 09:09:00 +01:00
evgeny 435ca204fe Clarify that repeated core start preserves the application running flag 2026-10-26 09:08:42 +01:00
evgeny 8640b45e99 Record instance lifecycle fixes, contracts and sanitizer audit evidence 2026-10-26 09:08:42 +01:00
evgeny 4219d5ce1d Specify reload behavior for repeated server sections in public header 2026-10-26 09:08:42 +01:00
evgeny 85e87cc9f8 Read radio hop list through aligned storage 2026-10-26 09:08:42 +01:00
evgeny e577daf6ab Describe conservative reload for duplicate and resolved IPv6 selectors 2026-10-26 09:08:42 +01:00
evgeny 0d6d1aeb19 Restart instances with duplicate server names to preserve all endpoints 2026-10-26 09:08:42 +01:00
evgeny a58f3516ab Clarify first-opened file logger ownership across instances 2026-10-26 09:08:42 +01:00
evgeny 44103038c0 Preserve selected global log path and verify database owner reload 2026-10-26 09:08:42 +01:00
evgeny 06ad255b95 Align instance guide and core lifecycle documentation with audited code 2026-10-26 09:08:42 +01:00
evgeny 9201d8c4f7 Use aligned PCM samples in headless radio integration fixture 2026-10-26 09:08:42 +01:00
evgeny ceaf71caf8 Align headless PCM before passing frames to Opus 2026-10-26 09:08:42 +01:00
evgeny 817e3744ee Reclaim cancelled heap timers before checking async resource counters 2026-10-26 09:08:42 +01:00
evgeny 68ead8c7dc Expose remaining async resource owners in instance regression test 2026-10-26 09:08:42 +01:00
evgeny 59f900810e Check headless clients, timer rollback and external subscription cleanup 2026-10-26 09:08:42 +01:00
evgeny 0d14613244 Document instance ownership, lifecycle, reload and callback contracts 2026-10-26 09:08:42 +01:00
evgeny f5488adab0 Release headless audio contexts, clients and timers on chat stop 2026-10-26 09:08:42 +01:00
evgeny fd93f39c78 Release remaining transport subscriptions at instance destruction 2026-10-26 09:08:42 +01:00
evgeny 1d92591780 Validate headless bindings and honor ephemeral ports in chat startup 2026-10-26 09:08:42 +01:00
evgeny 234c21fb6a Report outstanding allocations before instance teardown assertion 2026-10-26 09:08:42 +01:00
evgeny 88801318bb Include complete ETCP connection type in instance contract test 2026-10-26 09:08:42 +01:00
evgeny 9992228dcb Cover instance callbacks, constructor failures and selective/full reload 2026-10-26 09:08:42 +01:00
evgeny 4e32de8e65 Drain instance-owned sockets and registries without saved callback neighbors 2026-10-26 09:08:42 +01:00
evgeny a7d2333deb Reload complete endpoint settings and restart changed resource owners 2026-10-26 09:08:42 +01:00
evgeny 5e63bc2a42 Share atomic network index construction and typed socket teardown 2026-10-26 09:08:42 +01:00
evgeny b44ea19b4b Close config parser audit after the full integration suite 2026-10-26 09:08:42 +01:00
evgeny d681d5abf0 Record parser boundary, rollback and sanitizer audit evidence 2026-10-26 09:08:24 +01:00
evgeny 7ea1fa9954 Validate instance construction and retain the global log path safely 2026-10-26 09:08:24 +01:00
evgeny 372b7d7f65 Retain removed instance callbacks until nested dispatch completes 2026-10-26 09:08:24 +01:00
evgeny e5e61723d8 Inject config read faults through fortified fread as well 2026-10-26 09:08:24 +01:00
evgeny 7fe77a49c9 Restore console diagnostics after parser dump assertions 2026-10-26 09:08:24 +01:00
evgeny 9888820146 Describe parser validation, list order and service defaults 2026-10-26 09:08:23 +01:00
evgeny 9a7091b595 Document strict parser ownership and validate provided peer keys 2026-10-26 09:08:23 +01:00
evgeny 1041849030 Reject oversized service strings and cover scalar bounds 2026-10-26 09:08:23 +01:00
evgeny eff0446f8d Align boolean settings and timer bounds across parser and updater 2026-10-26 09:08:23 +01:00
evgeny e4852c82b4 Check service scalars and proxy ports before storing configuration 2026-10-26 09:08:23 +01:00
evgeny 99d52afd3f Validate global scalar options before narrowing or timer conversion 2026-10-26 09:08:23 +01:00
evgeny 4abeafa20e Normalize malformed key duplicates before strict config verification 2026-10-26 09:08:23 +01:00
evgeny 70b7823993 Use debug and socket test APIs with their declared contracts 2026-10-26 09:08:23 +01:00
evgeny 46bf5b8541 Test parser rejection, CIDR boundaries and allocation rollback 2026-10-26 09:08:23 +01:00
evgeny d21af324ac Validate network keys before use and keep secret keys out of dumps 2026-10-26 09:08:23 +01:00
evgeny f581fa423b Reject configuration when an option handler or allocation fails 2026-10-26 09:08:23 +01:00
evgeny bff354f9cc Validate complete protocol versions, network keys and endpoint ports 2026-10-26 09:08:23 +01:00
evgeny 7593120bd9 Parse CIDR, control endpoints and storage sizes without truncation 2026-10-26 09:08:23 +01:00
evgeny 869421cc05 Audit LAN docs and enforce stream member exclusions
Document LAN transport contracts and the completed part of the stream audit. Reject owner-deleted members before profile verification and add network lifecycle coverage for source, supplier and local member removal.

Validation: seven stream checks and all 195 core tests pass; proxy 9/9, burst and load 8/8 pass.
2026-10-26 08:55:31 +01:00
evgeny 6bd4690c3b Date transport audit completion after final sanitizer checks 2026-10-26 00:01:10 +01:00
evgeny 018f8a20f3 Close transport header audit and record integration validation 2026-10-26 00:00:11 +01:00
evgeny 13f379621a Keep route ACK fault tests effective with fortified libc calls 2026-10-25 23:57:53 +01:00
evgeny 8bacf73e86 Intercept fortified recvfrom in socket monitor fault tests 2026-10-25 23:56:40 +01:00
evgeny f327f7f434 Describe REALITY codec, protected stream and relay lifecycle 2026-10-25 23:53:34 +01:00
evgeny 5e7eb6290f Test STUN recheck with an existing and a newly discovered path 2026-10-25 23:52:41 +01:00
evgeny bdf0bdf873 Close REALITY relay cleanly when event monitoring fails 2026-10-25 23:52:41 +01:00
evgeny 2f4830a3d0 Recheck each STUN path once and clarify result validity 2026-10-25 23:51:47 +01:00
evgeny f37ab0824d Complete REALITY relay half-close on socket hangup 2026-10-25 23:49:47 +01:00
evgeny 7e526521eb Document REALITY session ownership and test relay failure cleanup 2026-10-25 23:48:38 +01:00
evgeny 88b05c07d9 Harden REALITY record lifetime, relay cleanup and input contracts 2026-10-25 23:40:56 +01:00
evgeny 47bf724748 Include errno in call ring I/O fault test 2026-10-25 23:37:09 +01:00
evgeny 2949101ff8 Test per-thread call traces, counter wrap and dump I/O errors 2026-10-25 23:30:56 +01:00
evgeny c0365ebb38 Keep teardown traces per thread and retain history across wrap 2026-10-25 23:29:45 +01:00
evgeny 9a13989c7e Document SOCKS ownership and cover empty UDP and input limits 2026-10-25 23:26:24 +01:00
evgeny 36900780f2 Preserve SOCKS stream data and make control startup cancellable 2026-10-25 23:25:16 +01:00
evgeny 6660f59b3f Fix automatic endpoint ownership, retries and scan teardown 2026-10-25 23:16:17 +01:00
evgeny f8c299c2e3 Test socket monitor address loss, callbacks and init faults 2026-10-25 22:58:54 +01:00
evgeny 9296b36366 Make socket monitoring bounded and cancel pending notifications 2026-10-25 22:56:45 +01:00
evgeny fe6b79127f Record passing packet dump sanitizer validation 2026-10-25 22:46:21 +01:00
evgeny dd81f7a665 Record packet dump fix and FreeBSD socket monitor finding 2026-10-25 22:44:55 +01:00
evgeny ce30ec5fe6 Align packet dump and CRC32 contracts with implementations 2026-10-25 22:43:43 +01:00
evgeny c3fa6d4db1 Exercise packet dump limits, protocols and fragment output 2026-10-25 22:32:22 +01:00
evgeny 235c2c4f4d Bound IPv4 packet dump reads and handle fragments 2026-10-25 22:32:22 +01:00
evgeny 9fb939ff24 Document unsafe packet dump reads found during audit 2026-10-25 22:32:22 +01:00
evgeny e035f53ab6 Fix stale socket references in connectivity probes 2026-10-25 22:30:52 +01:00
evgeny 8b0002e489 Disable UTUN by default in chat frontends and retain core bootstrap transports 2026-10-25 22:10:06 +01:00
evgeny fcc4a2cf42 Ignore zero-port addresses in connection manager candidates 2026-10-25 21:01:03 +01:00
evgeny 539f09004c Use channel member snapshots for desktop participant details 2026-10-25 20:04:59 +01:00
evgeny c832a5d7a5 Unify member snapshots and fix Android member status flicker 2026-10-25 19:29:44 +01:00
evgeny f09eb81381 Fix NAT stress test time helper on Windows 2026-10-25 18:24:07 +01:00
evgeny 59b3b9bd34 Check remote and local member-file ACL refusals separately 2026-10-25 18:10:58 +01:00
evgeny b3d3df5c57 Exercise signed LAN endpoints over isolated IPv6 interfaces 2026-10-25 18:06:46 +01:00
evgeny e75bd460b8 Avoid identity reload when removing expired LAN candidates 2026-10-25 18:00:56 +01:00
evgeny 77b43363fb Run signed LAN integration separately from other network tests 2026-10-25 18:00:01 +01:00
evgeny 199839b273 Cover socket reuse and TCP LAN recovery and document lifecycle 2026-10-25 17:58:18 +01:00
evgeny 8dd28fb90a Distinguish LAN nonce failures from ordinary unknown devices 2026-10-25 17:55:35 +01:00
evgeny 94a76e569e Respect SOCKS policy and report LAN lookup failures precisely 2026-10-25 17:55:34 +01:00
evgeny 09c7e0c937 Test signed LAN discovery, replay rejection and NCD recovery 2026-10-25 17:52:08 +01:00
evgeny 469f95c596 Apply nonce-verified LAN endpoints to offline NCD transports 2026-10-25 17:47:08 +01:00
evgeny 88c2d7a4e3 Share LAN interface matching for socket announcements and NCD 2026-10-25 17:44:52 +01:00
evgeny e8713e7a2c Load known node identities for verified LAN candidates 2026-10-25 17:43:21 +01:00
evgeny 28c447370a Add signed LAN endpoint announcements and nonce proofs 2026-10-25 17:42:40 +01:00
evgeny f276fda411 Restore Android core activity after internal restart 2026-10-25 17:20:42 +01:00
evgeny c26b626c35 Handle comments consistently in desktop socket protocol settings 2026-10-25 16:35:54 +01:00
evgeny 7bcdccc4d6 Verify autosocket protocol modes across IPv4 and IPv6 lifecycle 2026-10-25 16:35:54 +01:00
evgeny fc8a06547d Test automatic socket protocol configuration and Android port reuse 2026-10-25 16:35:54 +01:00
evgeny b1a07df606 Translate automatic socket protocol settings 2026-10-25 16:35:54 +01:00
evgeny 9d465bce16 Add Android autosocket protocol selection to network settings 2026-10-25 16:35:54 +01:00
evgeny eda65ece52 Generate Android autosockets per selected protocol and retain ports 2026-10-25 16:35:54 +01:00
evgeny ae85423e39 Add automatic socket protocol selector to desktop settings 2026-10-25 16:35:54 +01:00
evgeny f3bc5acacc Persist automatic socket protocols in desktop configuration 2026-10-25 16:35:54 +01:00
evgeny 556f6e0b9e Add selectable protocols for automatic transport sockets 2026-10-25 16:35:54 +01:00
evgeny 270b9fcf80 Merge remote-tracking branch 'origin/master' 2026-10-25 16:30:55 +01:00
evgeny 288b8091ce Document targeted recovery and retain scheduler diagnostics 2026-10-25 16:26:14 +01:00
evgeny 46f6c03147 Keep requests queued by callbacks for the next scheduler batch 2026-10-25 16:19:40 +01:00
evgeny 87dd27d022 Test targeted chat synchronization across peer events and service lifecycle 2026-10-25 16:13:53 +01:00
evgeny 2eade0a7c0 Scope deferred chat synchronization to channel and peer 2026-10-25 16:11:11 +01:00
evgeny 0e17756e19 Show stream playback buffer chains on desktop and Android
Send coalesced per-hop telemetry every 200 ms ahead of video DATA using the shared ETCP transport. Measure pending frames before ETCP handoff, retain stale and unavailable node values, and display the worst path with playback tempo.

Bump stream wire protocol to v7. Validate with 187 core tests, 21 desktop player tests, two Android indicator tests, and an Android APK build.
2026-10-25 15:21:23 +01:00
evgeny 5b5221189c Buffer stream PCM before playback and recover underruns without resets 2026-10-25 12:51:19 +01:00
evgeny 677f79881c Diagnose stream audio underruns and fixture timing jitter 2026-10-25 12:30:30 +01:00
evgeny 3ffacbfe37 Document stream recovery validation and existing Qt audio flake 2026-10-25 12:06:35 +01:00
evgeny c3cf86b9e0 Recover streams after five seconds and start from complete keys
Preserve queued media under backpressure, advertise retained keyframe ranges in stream wire v6, and reopen stalled subflows without resetting playback.

Cover large fragmented keys, sustained slow delivery, missing subflows, buffer eviction and stale bootstrap snapshots in integration regressions.
2026-10-25 12:03:49 +01:00
evgeny 4a785c2598 Improve stream recovery, delivery diagnostics and buffer indicators
Preserve essential FEC parts under pressure, coordinate stale-data gaps and reopen source subflows in parallel after transport failures.

Add per-peer network and playback diagnostics, Android and desktop buffer indicators, and regression coverage for Wi-Fi switching and congestion.
2026-10-25 01:18:02 +02:00
evgeny b7d74d8f87 Verify every NCD control ID byte and clarify new-socket scope 2026-10-24 20:27:57 +02:00
evgeny db0d7a1f47 Document NCD startup rollback reentrant lifetime and address snapshots 2026-10-24 20:24:22 +02:00
evgeny 9844fdefcb Align automatic socket documentation with shared NCD link matching 2026-10-24 20:24:22 +02:00
evgeny a353797edb Specify NCD ownership callbacks matching and fixed little-endian control wire 2026-10-24 20:22:45 +02:00
evgeny b83a28becc Keep NAT remeasurement fixture isolated from new direct helper links 2026-10-24 20:20:09 +02:00
evgeny a3f004772a Align ETCP fixtures with NCD identity and failed-open contracts 2026-10-24 20:20:09 +02:00
evgeny 702389d8d9 Retain NCD entry and transport through synchronous CLOSE callbacks 2026-10-24 20:18:15 +02:00
evgeny 88004f11ca Trigger NCD CLOSE on an empty unsuspended queue 2026-10-24 20:17:13 +02:00
evgeny 1f6f815917 Reproduce NCD teardown during synchronous CLOSE queue notification 2026-10-24 20:15:30 +02:00
evgeny 2a7266e17f Check IPv6 scope on the matching NCD link 2026-10-24 20:15:30 +02:00
evgeny e137778ba2 Exercise IPv6 REALITY guards and reentrant node snapshot replacement 2026-10-24 20:15:30 +02:00
evgeny 496a3c788e Cover NCD candidate policy constructor cancellation and nested removal 2026-10-24 20:15:30 +02:00
evgeny 772c0728e1 Use one NCD address matcher for opens updates and new sockets 2026-10-24 20:15:30 +02:00
evgeny b23d5e6047 Unify NCD opens and retain owners across failed startup and callbacks 2026-10-24 20:15:30 +02:00
evgeny 4695fe4371 Register NCD transport events atomically and reuse ETCP close lifecycle 2026-10-24 20:15:30 +02:00
evgeny 28c951ed9e Reject stale NCD notifications and validate complete control frames 2026-10-24 20:15:30 +02:00
evgeny 2cc5a6df91 Reproduce NCD startup failures stale events and malformed control 2026-10-24 20:15:30 +02:00
evgeny 10d6ddee38 Wait for target discovery before member file network transfers 2026-10-24 20:15:30 +02:00
evgeny 4314dff390 Expose CM and topology failures in member file network diagnostics 2026-10-24 20:14:58 +02:00
evgeny c311bb7a1f Prevent deferred CM readiness from restarting cancelled file transfers 2026-10-24 20:14:58 +02:00
evgeny b387c4b127 Preserve unowned member download temporaries on refusal and cancellation 2026-10-24 20:14:29 +02:00
evgeny 6d6afb4faa Align FULL and inline loss counters in dummynet documentation 2026-10-24 19:57:24 +02:00
evgeny e996e09f6e Specify dummynet datagram timing reconfiguration and filter ownership contracts 2026-10-24 19:57:24 +02:00
evgeny 8d035a065a Cover partial dummynet startup rollback without resource leaks 2026-10-24 19:57:24 +02:00
evgeny 0df339c384 Verify inline filters with real UDP delivery and independent ETCP teardown 2026-10-24 19:57:24 +02:00
evgeny c341a9b6cc Record passing full validation after ETCP diagnostics merge 2026-10-24 19:45:37 +02:00
evgeny 897cc007e1 Merge current master and reconcile completed member-files fixes 2026-10-24 19:38:40 +02:00
evgeny 6c9be8b134 Record full-suite failure deleting an unowned member-files temp 2026-10-24 19:26:27 +02:00
evgeny cfa0419576 Record repeated slow-duplex failures with native and real clocks 2026-10-24 19:09:34 +02:00
evgeny f8a2ecaabd Add isolated slow-duplex measurements and record BBR diagnosis 2026-10-24 19:07:18 +02:00
evgeny 79e37f64f8 Document member files audit findings and verified fixes 2026-10-24 18:47:06 +02:00
evgeny 4d729a2ff0 docs(member-files): align lifecycle and receipt retry behavior 2026-10-24 18:47:06 +02:00
evgeny 4f96926f6b docs(member-files): complete public request and transfer contracts 2026-10-24 18:47:06 +02:00
evgeny c1da55ad87 docs(member-files): clarify storage lifecycle and internal owners 2026-10-24 18:47:06 +02:00
evgeny f7b064a11a docs(member-files): specify wire codec and worker ownership 2026-10-24 18:47:06 +02:00
evgeny 41f0aa2439 fix(member-files): reject local FIFO without blocking disk worker 2026-10-24 18:47:06 +02:00
evgeny 1c1b2b2026 test(member-files): detect blocking open of local FIFO sources 2026-10-24 18:47:06 +02:00
evgeny 488577ac0e test(member-files): verify timed replay and bulk removal 2026-10-24 18:47:06 +02:00
evgeny 4d40b6f5f7 fix(member-files): bound busy retries by receipt lifetime 2026-10-24 18:47:06 +02:00
evgeny 2d8384830d test(member-files): cover bulk mutations and lost result replay 2026-10-24 18:47:06 +02:00
evgeny 0c8e9eef3c fix(member-files): retry busy mutations within replay guarantees 2026-10-24 18:47:06 +02:00
evgeny 20b4975d57 fix(member-files): prevent restart after early transfer cancellation 2026-10-24 18:47:06 +02:00
evgeny 0f42f92feb fix(member-files): clean up only owned download temporaries 2026-10-24 18:47:06 +02:00
evgeny 0b2dac3c5b test(member-files): retain route precondition after ABI diagnosis 2026-10-24 18:47:06 +02:00
evgeny 5df6d0c8f3 test(member-files): log startup state before transfer 2026-10-24 18:47:06 +02:00
evgeny a198cfb9e3 Bind inline dummynet filters to UDP link lifetime and report failures 2026-10-24 17:33:59 +02:00
evgeny 83bf76dd41 Release borrowed send-hook owners before ETCP link teardown 2026-10-24 17:33:59 +02:00
evgeny 36c096c4e9 Make UDP dummynet configuration and resource failures recoverable 2026-10-24 17:33:59 +02:00
evgeny 29d54ed20d Reproduce dummynet configuration datagram and timer failures 2026-10-24 17:33:59 +02:00
evgeny e59ef240e8 test(member-files): let transfer own initial route request 2026-10-24 17:33:47 +02:00
evgeny 27dd9e7b60 test(member-files): preserve unowned download temp on refusal 2026-10-24 17:33:47 +02:00
evgeny 8185b83eba Record final RTT timer, callback and network validation 2026-10-24 17:26:59 +02:00
evgeny 76afc56be8 Make RTT callback regression independent of host uptime 2026-10-24 17:26:59 +02:00
evgeny 5420a07ffc Refresh RTO before RTT callbacks can close the link 2026-10-24 17:26:59 +02:00
evgeny f00d67ca3c Trace refreshed RTO deadlines without per-packet debug noise 2026-10-24 17:26:59 +02:00
evgeny 90dff0b2f2 Refresh pending retransmit timer when timestamp RTT changes 2026-10-24 17:26:59 +02:00
evgeny 83734c920d Expose existing RTO timer refresh and regress timestamp shrink 2026-10-24 17:26:59 +02:00
evgeny e1dcee3c86 Record verified RTT filter and RTO recovery fixes 2026-10-24 17:26:59 +02:00
evgeny d5114f36b4 Clarify timestamp RTT role in transport contracts 2026-10-24 17:26:59 +02:00
evgeny 68a225baec Exercise RTT changes through real ETCP and document RTO inputs 2026-10-24 17:26:59 +02:00
evgeny ef404da44c Recover DATA RTT sampling after path delay increases 2026-10-24 17:26:59 +02:00
evgeny dbda8a24d7 Verify RTT hold rounds and document filter timing 2026-10-24 17:26:59 +02:00
evgeny bb462bad69 Preserve BBR RTT filter age and full-width probe deadlines 2026-10-24 17:26:59 +02:00
evgeny deee734e6c Record duplex validation and remaining BBR follow-ups 2026-10-24 17:26:59 +02:00
evgeny 8ff4a0bf46 Document ETCP receiver-clock bandwidth sampling 2026-10-24 17:26:59 +02:00
evgeny d2703b2145 Use receiver delivery clock for ETCP bandwidth samples 2026-10-24 17:26:59 +02:00
evgeny 9b72a0dadf Close media contract audit and record architecture review 2026-10-24 17:26:12 +02:00
evgeny 5e3701bb2f Clarify encrypted attachment MIME and UI contracts 2026-10-24 17:26:12 +02:00
evgeny 4bab1f7ea4 Align media delivery architecture docs with implementation 2026-10-24 17:26:12 +02:00
evgeny 9d9c82fb03 Document validated MIME fix and regression results 2026-10-24 17:26:12 +02:00
evgeny 99c1ee3394 test(media): cover encrypted MIME validation and side effect free rejection 2026-10-24 17:26:11 +02:00
evgeny d88e39fb4e chat: reject unsupported encrypted attachment types before side effects 2026-10-24 17:26:11 +02:00
evgeny f63d640c95 media: share bounded content type validation in encrypted containers 2026-10-24 17:26:11 +02:00
evgeny 86b7f9cf44 docs(media): record accepted but unreadable MIME containers 2026-10-24 17:26:11 +02:00
evgeny f331d177ca docs(media): clarify preparation ownership and active protocol commands 2026-10-24 17:26:11 +02:00
evgeny 28bbd62d74 docs(media): specify attachment metadata and voice file contracts 2026-10-24 17:26:11 +02:00
evgeny c1717d4047 docs(media): record validated SQLite announcement fix 2026-10-24 17:26:11 +02:00
evgeny 4bfdb1dcc2 test(media): restore console after SQL diagnostic assertions 2026-10-24 17:26:11 +02:00
evgeny 6e3be1aaf3 test(media): verify exact announcement identities after SQL recovery 2026-10-24 17:26:11 +02:00
evgeny eea2b22c4e test(media): cover malformed local announcements and SQLite failures 2026-10-24 17:26:11 +02:00
evgeny 81fc4291db media: validate SQLite records before local block announcements 2026-10-24 17:26:11 +02:00
evgeny 1a212489fd docs(media): correct announcement function reference 2026-10-24 17:26:11 +02:00
evgeny 0d616ce1e7 docs(media): record unchecked SQLite announcements and fix plan 2026-10-24 17:26:11 +02:00
evgeny 7ff8e1f15a docs(media): specify crypto and file transfer ownership contracts 2026-10-24 17:26:11 +02:00
evgeny 40e2fe2e27 docs(media): record validated voice duration fix 2026-10-24 17:26:11 +02:00
evgeny 359a9f3dfc test(media): cover voice duration bounds and early rejection 2026-10-24 17:26:11 +02:00
evgeny 68a7695d81 media: reject voice duration by complete frames before encoding 2026-10-24 17:26:11 +02:00
evgeny 6f3d634c77 media: share attachment duration limit 2026-10-24 17:26:11 +02:00
evgeny 4177ab3536 docs(media): record voice duration boundary defect and fix plan 2026-10-24 17:26:11 +02:00
evgeny 80558f6686 Merge remote-tracking branch 'origin/master' 2026-10-24 17:15:42 +02:00
evgeny da5cf6fc99 Prepare signed existing members before end-to-end CHAT joining 2026-10-24 17:00:53 +02:00
evgeny e6e866a41a Seed complete members in isolated database sync fixtures 2026-10-24 17:00:53 +02:00
evgeny e1675f6910 Preserve chat stress failure logs and group admission diagnostics 2026-10-24 16:56:52 +02:00
evgeny bb13824ad8 Complete NAT wire lifecycle scheduling and diagnostic contracts 2026-10-24 16:53:10 +02:00
evgeny 857a4cee2f Exercise NAT startup rollback and UDP timeout allocation failure 2026-10-24 16:52:10 +02:00
evgeny a6444725da Reject UDP probes when their timeout cannot be scheduled 2026-10-24 16:51:34 +02:00
evgeny 4a00da31da Document complete membership queries separately from row presence 2026-10-24 16:50:41 +02:00
evgeny af50fde9d9 Verify CHAT admission excludes placeholders and deleted members 2026-10-24 16:50:41 +02:00
evgeny f1b62f9112 Require active complete membership for CHAT group admission 2026-10-24 16:46:01 +02:00
evgeny 0b4997c5d5 Release removed NAT helper sockets and reject partial startup 2026-10-24 16:40:51 +02:00
evgeny b8dd2b8cc5 Verify media cancellation without reading a closed CM handle 2026-10-24 16:31:49 +02:00
evgeny 6cfd88afcf Reject zero CM request ids before creating peer state 2026-10-24 16:25:27 +02:00
evgeny 8e7fb1f31b Reconcile CM protocol scheduling cache and cleanup contracts 2026-10-24 16:24:30 +02:00
evgeny 00a85a1468 Keep local CM demand after stale control and reject zero requests 2026-10-24 16:22:15 +02:00
evgeny 182fb97970 Remove obsolete CM disconnect and clarify service ownership 2026-10-24 16:22:15 +02:00
evgeny e6a812042f Check CM bootstrap ownership and mandatory monitor timers 2026-10-24 16:17:20 +02:00
evgeny 2f3cf0933c Keep READY intermediaries eligible and test CM allocation failures 2026-10-24 16:14:48 +02:00
evgeny 80451c43be Make CM cleanup allocation-free and reject incomplete startup 2026-10-24 16:09:39 +02:00
evgeny 007f7c8ae8 Preserve group attachment before transport readiness 2026-10-24 16:01:29 +02:00
evgeny f541ab428b Describe BGP commit boundaries and diagnose initialization failures 2026-10-24 15:57:40 +02:00
evgeny 7ebfddfc4b Clarify group processing callbacks and failed route installation 2026-10-24 15:56:36 +02:00
evgeny 56d513ed85 Inject topology pool database registry and radio timer failures 2026-10-24 15:52:39 +02:00
evgeny d1562bdd0e Check that late BGP allocation failure preserves accepted state 2026-10-24 15:51:43 +02:00
evgeny 145dd1e5ab Prepare BGP paths before committing received node state 2026-10-24 15:50:17 +02:00
evgeny ab5c077600 Unwind topology initialization on pool and SQLite failures 2026-10-24 15:49:42 +02:00
evgeny 6b413d67a6 Exercise group creation rollback radio retry and BGP subnets 2026-10-24 15:48:58 +02:00
evgeny 4363a424d0 Reject incomplete groups and refresh BGP subnet ownership 2026-10-24 15:47:28 +02:00
evgeny 086eefed55 Keep both test transports owned while checking invite timeout 2026-10-24 15:41:16 +02:00
evgeny 5e8ff95c99 Verify invite deadlines and transport loss with shared owners 2026-10-24 15:38:42 +02:00
evgeny 21d8b3844e Apply refreshed peer priorities without replacing group requests 2026-10-24 15:36:12 +02:00
evgeny a7ffaf497e Include concrete transport state in invite regression tests 2026-10-24 15:30:37 +02:00
evgeny 9ce0abe5a9 Cover invite response bounds isolation and failure propagation 2026-10-24 15:30:04 +02:00
evgeny 483e89cd79 Validate channel descriptions and isolate invite request ownership 2026-10-24 15:28:44 +02:00
evgeny 4d9e624f8e Reconcile router protocol and architecture with implementation 2026-10-24 15:15:35 +02:00
evgeny bafda5ae3a Merge origin/master with encrypted attachment ownership fixes
Validation: ./build.sh --no-gui -j4 and make check -j4 passed; 186 tests, no failures.
2026-10-24 15:11:50 +02:00
evgeny 09e620e12a Specify router local delivery, callbacks, flow control and reset contracts 2026-10-24 15:10:06 +02:00
evgeny 3bd9b964fa Remove obsolete router state and clarify receive diagnostics 2026-10-24 15:07:41 +02:00
evgeny a258b77240 Cancel pending transit queues when destroying the router 2026-10-24 15:06:48 +02:00
evgeny 936bacbe4b Clarify encrypted output cleanup contract on filesystem errors 2026-10-24 15:00:05 +02:00
evgeny 1227027c2f Record validated encrypted attachment ownership fix and remaining audit scope 2026-10-24 14:59:12 +02:00
evgeny d8089f8d12 Release router unit fixture registry ownership completely 2026-10-24 14:56:23 +02:00
evgeny 4862a52684 Document encrypted attachment preparation publication and recovery ownership 2026-10-24 14:55:24 +02:00
evgeny e40d8de1b2 Keep full router jitter precision in monitor snapshots 2026-10-24 14:54:48 +02:00
evgeny dbf6bb759c Preserve the unsigned range of router RTT jitter 2026-10-24 14:54:48 +02:00
evgeny be0bd224fa Use canonical media base throughout attachment recovery 2026-10-24 14:51:32 +02:00
evgeny 6bf6d99b9c Test service cancellation after encrypted attachment rename 2026-10-24 14:50:32 +02:00
evgeny 7caebc5a11 Verify attachment recovery preserves active temp owners across restarts 2026-10-24 14:48:25 +02:00
evgeny 6c13755a5c Reject invalid local router payloads and report delivery failures 2026-10-24 14:48:04 +02:00
evgeny c6f28571b7 Keep local callback context private and fully detach services 2026-10-24 14:46:33 +02:00
evgeny 76ba7aae6a Cover encrypted file aliases and I/O failures through publication 2026-10-24 14:45:32 +02:00
evgeny 066b895055 Remove closing router channels before notifying services 2026-10-24 14:44:22 +02:00
evgeny a297d2d649 Record validated ACK batching and remaining solo duplex limits 2026-10-24 14:43:03 +02:00
evgeny f09d76e3fd Recover owned encrypted attachment temporaries in both storage trees 2026-10-24 14:43:03 +02:00
evgeny 7737391ded Document absolute ACK scheduling and cross-path precedence 2026-10-24 14:43:03 +02:00
evgeny dc08256025 Clarify due ACK precedence and bounded burst behavior 2026-10-24 14:43:03 +02:00
evgeny 72d7405a97 Serve due path ACKs before DATA on another link 2026-10-24 14:43:03 +02:00
evgeny 73096e8e3e Verify ACK deadlines through link down and removal 2026-10-24 14:43:03 +02:00
evgeny 51c667edd8 Distinguish early ACK packets from legitimate batched entries 2026-10-24 14:43:03 +02:00
evgeny 2edf09fde1 Cover ACK batching deadlines, timer races, and failure cleanup 2026-10-24 14:43:03 +02:00
evgeny 6ab2526966 Align ACK contracts and diagnostics with deadline state 2026-10-24 14:43:03 +02:00
evgeny c1b0772071 Honor absolute ACK deadlines across wakes and piggyback 2026-10-24 14:43:03 +02:00
evgeny 159237a70c Define absolute ACK deadlines and urgent fallback contracts 2026-10-24 14:43:03 +02:00
evgeny c8051619c1 Reproduce premature ACKs before their absolute deadline 2026-10-24 14:43:03 +02:00
evgeny 2b74d2bf4f Record final queue diagnostics validation and observations 2026-10-24 14:43:03 +02:00
evgeny 35bd19b6c0 Observe ACK queue peaks before immediate send 2026-10-24 14:43:03 +02:00
evgeny 7e166c650c Document multipath diagnostics and the ACK deadline defect 2026-10-24 14:43:03 +02:00
evgeny 055ffa27b2 Add offline multipath charts and count timestamped ACKs 2026-10-24 14:43:03 +02:00
evgeny cd3cf38f06 Expose callback and stream progress in multipath snapshots 2026-10-24 14:43:03 +02:00
evgeny 12b0ab437e Capture buffered multipath queue and pacing diagnostics 2026-10-24 14:43:03 +02:00
evgeny a9bbb470c2 Record full validation of retry scheduling changes 2026-10-24 14:43:03 +02:00
evgeny 6894c66f3a Record passing fault matrix and remaining duplex limits 2026-10-24 14:43:03 +02:00
evgeny a2f9b76d10 Record retry scheduler architecture and regression coverage 2026-10-24 14:43:03 +02:00
evgeny 3d40951e66 Clarify input resumption with queued DATA 2026-10-24 14:43:03 +02:00
evgeny 4350b54769 Publish attachment output once and preserve ownership through cancellation 2026-10-24 14:41:39 +02:00
evgeny 92d52d25a8 Prepare encrypted attachments in exclusively owned durable temporaries 2026-10-24 14:40:53 +02:00
evgeny 9e0949434e Preserve video temp mode and test durable file commit boundaries 2026-10-24 14:39:46 +02:00
evgeny aa7a9b74f4 Select ordinary temporary file mode for copies and media blocks 2026-10-24 14:38:54 +02:00
evgeny 12556344b0 Add durable owned temporary file lifecycle and shared publication helpers 2026-10-24 14:38:34 +02:00
evgeny 2e3ab00ce6 Design owned temporary output and durable publication for encrypted attachments 2026-10-24 14:34:00 +02:00
evgeny f92c78a2e0 Merge remote-tracking branch 'origin/master' 2026-10-24 14:33:18 +02:00
evgeny 7c7c316c3f Document atomic local publication and bootstrap cleanup 2026-10-24 14:25:18 +02:00
evgeny 94aaf3c8e3 Align topology model documentation with current runtime contracts 2026-10-24 14:23:50 +02:00
evgeny c282d03f25 Describe NODEINFO byte layout, identity and registry semantics 2026-10-24 14:20:29 +02:00
evgeny f7db49fc97 Cover local topology replacement allocation failures 2026-10-24 14:18:42 +02:00
evgeny 8cc97d2ffe Record reproducible encrypted file alias data loss during media audit 2026-10-24 14:17:35 +02:00
evgeny f9994e11b5 Clarify local update ownership, results and failure contracts 2026-10-24 14:17:13 +02:00
evgeny 1e0281d4d8 Prepare local topology replacements before retiring old state 2026-10-24 14:16:39 +02:00
evgeny 42a58881ca Document SQLite snapshots, projections and membership contracts 2026-10-24 14:13:26 +02:00
evgeny 19c3cc0434 Reject interrupted membership channel queries 2026-10-24 14:10:28 +02:00
evgeny 81e2a9aa4a Return peer lists atomically after successful SQL iteration 2026-10-24 14:09:36 +02:00
evgeny 575a3788e3 Roll back failed channel deletion and node classification 2026-10-24 14:07:28 +02:00
evgeny 461417beac Record completed proxy fixes and architecture validation results 2026-10-24 14:03:56 +02:00
evgeny 26b5da6835 Release partial SQL bootstrap records on allocation failures 2026-10-24 14:03:48 +02:00
evgeny 99608de811 Reject failed topology writes and malformed stored signatures 2026-10-24 14:01:37 +02:00
evgeny 5c4207c145 Keep resolved routing audit details out of the task backlog 2026-10-24 14:00:22 +02:00
evgeny a42dc38874 Check real raw ICMP explicitly alongside deterministic loopback 2026-10-24 14:00:17 +02:00
evgeny 83194b19c7 Use supported TCP proxy exit option in TUN integration fixture 2026-10-24 13:59:29 +02:00
evgeny 14c5ddf864 Propagate failures when storing verified node identities 2026-10-24 13:57:05 +02:00
evgeny f10a6f70c5 Describe checked datagram startup and bounded TCP HUP handling 2026-10-24 13:54:40 +02:00
evgeny e2ee5f2397 Document atomic proxy client creation and instance shutdown order 2026-10-24 13:52:22 +02:00
evgeny 324b289968 Bound topology dump writes and return the actual length 2026-10-24 13:45:08 +02:00
evgeny 5914e26579 Update datagram and TCP exit documentation for explicit ownership 2026-10-24 13:42:20 +02:00
evgeny 2894e06014 Document HUP polling contract and isolate ICMP fault injection 2026-10-24 13:41:16 +02:00
evgeny d0edacb7b9 Test HUP registration failure and teardown with pending TCP writes 2026-10-24 13:39:50 +02:00
evgeny 1ce285c09b Preserve datagram bindings and verify optional ICMP behavior 2026-10-24 13:38:45 +02:00
evgeny 8dcd2fac3b Record topology dump truncation defect found during audit 2026-10-24 13:37:22 +02:00
evgeny bb2ef05157 Roll back required TUN mappings and verify instance startup failures 2026-10-24 13:36:22 +02:00
evgeny c4eddfe50e Cover proxy startup rollback and datagram socket failures 2026-10-24 13:34:51 +02:00
evgeny f0629ea679 Exercise orderly and abrupt TLS shutdown in proxy integration 2026-10-24 13:29:45 +02:00
evgeny 4da9d85545 Honor TCP read backpressure across HUP and restore polling 2026-10-24 13:28:44 +02:00
evgeny d5444fb9bc Check UDP socket operations and roll back incomplete flows 2026-10-24 13:25:43 +02:00
evgeny 50da7fe457 Make TCP proxy construction atomic and retain instance datagrams 2026-10-24 13:24:30 +02:00
evgeny 99be040488 Separate ICMP exit startup from shared context ownership 2026-10-24 13:23:58 +02:00
evgeny 902ffa05b4 Record NODEINFO parsing fix and sanitizer validation 2026-10-24 13:21:42 +02:00
evgeny 051b13e161 docs(proxy): align planned teardown with instance ownership 2026-10-24 13:18:52 +02:00
evgeny 04ace670ed docs(proxy): design error handling and lifecycle fixes 2026-10-24 13:17:33 +02:00
evgeny 99dd48480f Align REALITY round-trip fixture with NODEINFO ownership 2026-10-24 13:09:16 +02:00
evgeny acd9dcd1a8 Cover empty NODEINFO outputs and malformed BGP preservation 2026-10-24 13:03:42 +02:00
evgeny 790978458c Make NODEINFO section parsing independent of requested outputs 2026-10-24 13:01:30 +02:00
evgeny f9a3830416 Add NODEINFO wire parsing and allocation regressions 2026-10-24 12:59:00 +02:00
evgeny 5f51149622 Record routing audit progress and NODEINFO parsing defect 2026-10-24 12:42:47 +02:00
evgeny 0688ffc26d docs(proxy): qualify integration audit results 2026-10-24 12:39:54 +02:00
evgeny ec1fc52da1 docs(proxy): record teardown findings and refine counters 2026-10-24 12:39:09 +02:00
evgeny 5e80a9cc6c docs(proxy): consolidate current protocol and audit coverage 2026-10-24 12:38:27 +02:00
evgeny f003aaa92d docs(proxy): reconcile TCP client server and listener behavior 2026-10-24 12:36:16 +02:00
evgeny bf03348c64 Correct connectivity probe and IPv4 routing documentation 2026-10-24 12:19:22 +02:00
evgeny 0445c38c31 Clarify address profiles and route statistics contracts 2026-10-24 12:18:30 +02:00
evgeny 30a69712fc Align route table and observation documentation 2026-10-24 12:17:44 +02:00
evgeny 27cf6ae365 docs(proxy): document per-instance datagram contexts 2026-10-24 12:16:47 +02:00
evgeny 1ad8ff73ad Document routing helper ownership and wire contracts 2026-10-24 12:16:31 +02:00
evgeny 0bc0d6cc62 Enforce disjoint IPv4 route insertion atomically 2026-10-24 12:15:29 +02:00
evgeny 23cec465bf docs(proxy): specify TCP lifecycle and UDP ownership 2026-10-24 12:14:42 +02:00
evgeny a4abe30b18 docs(proxy): clarify flow control and HTTP parser contracts 2026-10-24 12:13:05 +02:00
evgeny 34d1dcb7c8 Document send scanning, retry rounds, and fast stall recovery 2026-10-24 12:01:20 +02:00
evgeny 93bf846fc4 Preserve retry priority during bounded burst measurements 2026-10-24 11:46:42 +02:00
evgeny c87cc6e4a2 Match the input waiter callback signature 2026-10-24 11:41:39 +02:00
evgeny 1fbd1e466b Verify retry history, stall recovery, and admission callbacks 2026-10-24 11:39:31 +02:00
evgeny b4d5da1df2 Wait for both configured RTOs in queue bypass regression 2026-10-24 11:35:25 +02:00
evgeny ff74ac8295 Scan past blocked DATA while prioritizing sendable retries 2026-10-24 11:31:46 +02:00
evgeny dcd6cd93c4 Select unused retry paths before starting another round 2026-10-24 11:29:13 +02:00
evgeny d439ee7ca7 Track stalled DATA paths and accepted retry rounds safely 2026-10-24 11:28:29 +02:00
evgeny 39ee5b392b Define retry path history and fast stall state contracts 2026-10-24 11:27:48 +02:00
evgeny acde6bda9d Test send queue bypass, retry priority, and bounded admission 2026-10-24 11:22:28 +02:00
evgeny 8167e0e5f5 Record recovery stage checks and repeated stalled-path cycles 2026-10-24 10:43:25 +02:00
evgeny 5a32d08ffd Buffer retry choice diagnostics until measurement completes 2026-10-24 10:32:44 +02:00
evgeny b98b87ea12 Explain retry choices between stalled multipath channels 2026-10-24 10:26:14 +02:00
evgeny 05d3fa30d9 Record path history for the fragment blocking delivery 2026-10-24 10:19:36 +02:00
evgeny 516ed04897 Identify the fragment behind maximum multipath message latency 2026-10-24 10:18:11 +02:00
evgeny 1d295c7d3a Measure multipath recovery stages separately from RTO waits 2026-10-24 10:05:13 +02:00
evgeny 1c6a7e7bf9 Remove speculative early retries from the ETCP plan 2026-10-24 09:56:54 +02:00
evgeny f1f4976222 Record retry recovery status and full regression results 2026-10-24 09:48:19 +02:00
evgeny 14515ca446 Document retry wait policy and fault recovery measurements 2026-10-24 09:46:38 +02:00
evgeny 8dd03c2b5c Wait for another UP path before retrying ETCP DATA 2026-10-24 09:38:20 +02:00
evgeny 412b9bc713 Test retry waiting for another available ETCP path 2026-10-24 09:34:21 +02:00
evgeny ff2860ffbc Record pacer validation and remaining multipath failures 2026-10-24 09:09:42 +02:00
evgeny c7a530092d Check pacer reset callback against its actual contract 2026-10-24 02:54:41 +02:00
evgeny deac10e3f6 Wake ETCP pacer at its first permitted transmit time 2026-10-24 02:49:25 +02:00
evgeny 42c4195f2e Test pacer eligibility boundaries and readiness lifecycle 2026-10-24 02:25:23 +02:00
evgeny ce3d942efe Record multipath baseline and verify pacer wakeup defect 2026-10-24 02:17:38 +02:00
evgeny a22a27b7a9 Record validated signature lifecycle fix and exact contracts 2026-10-24 01:15:49 +02:00
evgeny 7d57b484d8 Focus signature test logs on lifecycle and failure stages 2026-10-24 01:10:12 +02:00
evgeny 44acb5aecf Document streaming signature state ownership and retries 2026-10-24 01:03:24 +02:00
evgeny 5d11f90cd4 Make streaming signature initialization and cleanup safe 2026-10-24 01:02:10 +02:00
evgeny 4824f3523d Test streaming signature ownership and OpenSSL failures 2026-10-24 01:00:36 +02:00
evgeny 5a7823e6ef Record streaming signature OOM defect and completed temp fix 2026-10-24 00:46:40 +02:00
evgeny 5792db996c Clarify crypto key derivation and actual module dependencies 2026-10-24 00:44:29 +02:00
evgeny 16a33ac9f7 Correct remaining crypto examples and streaming signature buffer contract 2026-10-24 00:37:18 +02:00
evgeny 3afd31e561 Align crypto documentation with random CCM nonces and public-key node IDs 2026-10-24 00:35:13 +02:00
evgeny 2715faffff Document receiver-bounded BBR samples and diagnostic input contracts 2026-10-24 00:33:19 +02:00
evgeny 9459b43211 Remove stale pacing and handshake descriptions from ETCP protocol specification 2026-10-24 00:32:42 +02:00
evgeny 964f6cb045 Correct ETCP diagnostic filters and state dump documentation 2026-10-24 00:30:33 +02:00
evgeny bed99abbe9 Clarify STCP client ownership, ping lifetime and handshake byte order 2026-10-24 00:28:58 +02:00
evgeny d6eecd6f1c Document STCP listener arguments, accepted ownership and current handshake phases 2026-10-24 00:27:56 +02:00
evgeny ecdd767934 Align connection documentation with current UDP sessions and keepalive wire format 2026-10-24 00:27:14 +02:00
evgeny 1cf2cc10dd Keep file I/O return-value overview consistent with orphan cleanup API 2026-10-24 00:21:25 +02:00
evgeny 39f9d6a0e9 Keep active block and worker temporaries during media cache cleanup 2026-10-24 00:16:57 +02:00
evgeny e84c66a3d3 Reproduce orphan cleanup during a real encrypted attachment transfer 2026-10-24 00:15:16 +02:00
evgeny e195894048 Protect owned temporary files from concurrent orphan removal 2026-10-24 00:13:18 +02:00
evgeny ee437b9473 Align ETCP header declarations, timestamp units and UDP contracts with code 2026-10-24 00:06:45 +02:00
evgeny 299c613760 Correct ETCP API callback and datagram ownership documentation 2026-10-24 00:06:00 +02:00
evgeny 74b63cc315 Verify ETCP registry identity and failure ownership invariants 2026-10-24 00:01:02 +02:00
evgeny 032f8e83b2 Publish incoming UDP peers before callbacks and preserve accepted ownership 2026-10-23 23:57:51 +02:00
evgeny c7d7789a58 Reuse ETCP registry entries and reject duplicate peer indexing 2026-10-23 23:57:32 +02:00
evgeny fb995db489 Cover UDP accept cancellation with surviving paths and NCD owners 2026-10-23 23:50:39 +02:00
evgeny 942736d604 Check accepted and rejected MTU boundaries in both UDP handshake directions 2026-10-23 23:42:49 +02:00
evgeny b8021efed8 Validate UDP handshake MTU and nonzero path IDs before state updates 2026-10-23 23:41:58 +02:00
evgeny 1260884485 Exercise invalid UDP INIT path identifiers and MTU limits 2026-10-23 23:40:37 +02:00
evgeny 52d9077bb5 Describe retained link scopes and callback-safe RX timeouts 2026-10-23 23:37:44 +02:00
evgeny 519a2ee242 Cover UDP callback deletion, connection close and path replacement 2026-10-23 23:35:55 +02:00
evgeny 6d6ec7e725 Keep RX timeout and link-status callbacks inside retained link scopes 2026-10-23 23:31:16 +02:00
evgeny d0a168f89e Retain ETCP links across callbacks and release closed paths on scope exit 2026-10-23 23:30:43 +02:00
evgeny 5ccd47dd17 Bind incoming UDP INIT identity to the authenticated key 2026-10-23 23:17:25 +02:00
evgeny 2f6ff9303e Reject authenticated INIT requests claiming another node identity 2026-10-23 23:17:01 +02:00
evgeny d9aede4138 Drain pending UDP traffic before snapshotting INIT validation state 2026-10-23 23:13:03 +02:00
evgeny 0860b1e06d Validate the complete UDP INIT request body before reading fields 2026-10-23 23:09:27 +02:00
evgeny 10927b1d08 Allow early wire rejection in INIT request boundary tests 2026-10-23 23:06:23 +02:00
evgeny 3a8cc8a326 Exercise encrypted UDP INIT request body boundaries 2026-10-23 23:03:48 +02:00
evgeny bf7464a4d9 Document connection ownership after a cancelled TCP accept 2026-10-23 22:53:58 +02:00
evgeny e51badebcb Preserve active owners and paths when an incoming TCP link is cancelled 2026-10-23 22:53:36 +02:00
evgeny d5d103148f Test ownership handoff while cancelling an incoming TCP path 2026-10-23 22:52:40 +02:00
evgeny d5721563fc Clarify NEW cancellation and subscription mutation semantics 2026-10-23 22:43:09 +02:00
evgeny 274554f7a5 Cover TCP creation cancellation and self-unsubscription on both roles 2026-10-23 22:42:20 +02:00
evgeny 8fe1011da2 Document constructor cancellation and link memory ownership 2026-10-23 22:41:42 +02:00
evgeny 21a4dd7a70 Exercise callback unsubscription and nested dispatch on all ETCP chains 2026-10-23 22:40:47 +02:00
evgeny 33912355d6 Keep removed ETCP subscriptions until the outer dispatch returns 2026-10-23 22:39:56 +02:00
evgeny 5178f7abc6 Define instance callback dispatch lifetime for safe unsubscription 2026-10-23 22:39:06 +02:00
evgeny d0ee0341c5 Verify cancelled link constructors and guard UDP handshake callbacks 2026-10-23 22:36:39 +02:00
evgeny a2861b0570 Keep cancelled links alive until their constructor returns 2026-10-23 22:35:14 +02:00
evgeny a51c080407 Return NULL when callbacks cancel ETCP connection creation 2026-10-23 22:34:46 +02:00
evgeny 2ea4fb94ab Test nested deletion of the current and neighboring ETCP paths 2026-10-23 22:03:58 +02:00
evgeny 986193055e Suppress stale connection UP after its callback removes the last path 2026-10-23 22:03:29 +02:00
evgeny a43d478495 Cover close from connection INIT and UP callbacks on both roles 2026-10-23 22:02:44 +02:00
evgeny bf5a128a05 Correct STCP close contracts and sanitizer issues in its test 2026-10-23 22:01:48 +02:00
evgeny 477d8f995b Document STCP adapter ownership, callbacks and reconnect lifecycle 2026-10-23 21:59:12 +02:00
evgeny 03d69cb772 Verify TCP retry timing, recovery and cancellation end to end 2026-10-23 21:58:27 +02:00
evgeny f5e4c78b8c Exercise repeated close during the server link teardown event 2026-10-23 21:57:10 +02:00
evgeny 425e1a527b Provide the peer snapshot for the incoming test owner 2026-10-23 21:56:35 +02:00
evgeny f1e3c2c08a Hold the incoming connection before exercising DOWN callbacks 2026-10-23 21:55:54 +02:00
evgeny bd9f1bb0c9 Flush cancelled timers in teardown tests and clarify adapter close 2026-10-23 21:54:49 +02:00
evgeny 1fb52d3f5b Report active resources when callback teardown is unbalanced 2026-10-23 21:54:15 +02:00
evgeny 4614577d19 Stop readiness publication after callback close and rescan teardown links 2026-10-23 21:49:11 +02:00
evgeny f37221107d Guard TCP link transitions across callbacks and unify reconnect backoff 2026-10-23 21:48:11 +02:00
evgeny 42e7b9b1b6 Own STCP adapter queues and report connection failures before READY 2026-10-23 21:46:12 +02:00
evgeny 7753a0f11e Include the raw STCP server API in adapter regression tests 2026-10-23 21:43:17 +02:00
evgeny 4bfec7257f Cover TCP callback teardown on both roles and guard link close reentry 2026-10-23 21:40:43 +02:00
evgeny 2cad81050d Exercise early STCP adapter failure and cancellation callbacks 2026-10-23 21:39:32 +02:00
evgeny 18f10b23b3 Record compact attempt validation and aggregation check 2026-10-23 19:34:46 +02:00
evgeny a3eeebbc52 Clarify attempt reservation ownership on epoch exhaustion 2026-10-23 19:33:11 +02:00
evgeny 85c92e35a8 Update multipath contract for compact attempt pairs 2026-10-23 19:30:22 +02:00
evgeny be95e93a36 Reject old encrypted ACKs when compact attempt pairs restart in a new epoch 2026-10-23 19:27:06 +02:00
evgeny 7c09bfca7f Stop packet construction when input callbacks restart the stream 2026-10-23 19:26:00 +02:00
evgeny 77a737fd71 Document compact attempt wire layout and epoch reuse protection 2026-10-23 19:25:20 +02:00
evgeny 9a9517deab Exercise ACK splitting beyond compact entry capacity 2026-10-23 19:24:52 +02:00
evgeny b73d6e91e2 Verify compact attempt isolation, wire boundaries and exhaustion recovery 2026-10-23 19:23:30 +02:00
evgeny 0987d9dd04 Adapt encrypted session and window fixtures to compact attempt fields 2026-10-23 19:20:49 +02:00
evgeny ccbd214c97 Encode 16-bit attempt numbers and guard pair reuse by session epochs 2026-10-23 19:19:54 +02:00
evgeny 6414cb15ef Define compact per-fragment ETCP attempt numbers 2026-10-23 19:19:07 +02:00
evgeny 8c3fcfd1c8 Log fragment bytes and session epochs on normalizer desync 2026-10-23 18:15:17 +02:00
evgeny 1b7d314d85 Record bandwidth-only correction validation and remaining speed limits 2026-10-23 16:48:47 +02:00
evgeny ea5a0b7d5a Describe receiver-clock bandwidth bounds and ACK wire format 2026-10-23 16:44:07 +02:00
evgeny 6fc964031c Check ACK receiver point diagnostics at buffer boundaries 2026-10-23 16:40:52 +02:00
evgeny 4bf47ca357 Exercise receiver bandwidth bounds and ACK progress framing 2026-10-23 16:39:12 +02:00
evgeny ea4a92125b Carry receiver progress only in ACKs with attempt confirmations 2026-10-23 16:23:20 +02:00
evgeny 5586528555 Bound ETCP bandwidth samples by receiver delivery progress 2026-10-23 16:22:13 +02:00
evgeny e8d9d683dc Record duplex plan trials and measured ACK bandwidth costs 2026-10-23 16:10:46 +02:00
evgeny cc01457957 Record verified INIT recovery and BGP regression results 2026-10-23 14:24:31 +02:00
evgeny 5b8aba9c8b Drive callback deletion through the public reinit transition 2026-10-23 14:19:53 +02:00
evgeny f5d67d5240 Test link deletion from INIT and keepalive callbacks 2026-10-23 14:19:24 +02:00
evgeny 35ef504423 Document INIT liveness and response validation contracts 2026-10-23 14:16:28 +02:00
evgeny a87d3116af Validate INIT response body before updating peer state 2026-10-23 14:14:53 +02:00
evgeny c5f743a09d Cover INIT liveness with an independent healthy link 2026-10-23 14:01:57 +02:00
evgeny b167a27e85 Document RX ownership and limit readiness wakeups to transitions 2026-10-23 13:48:09 +02:00
evgeny f00a5bd306 Apply INIT reachability before reply and publish guarded RX transitions 2026-10-23 13:45:23 +02:00
evgeny 608caf01c1 Initialize the liveness fixture crypto and drain cancelled timers 2026-10-23 13:41:59 +02:00
evgeny e801fce2c6 Add encrypted UDP INIT liveness and one-way recovery regression 2026-10-23 13:38:36 +02:00
evgeny e89948f5ed Include the lowest reverse solo rate in measurement summary 2026-10-23 13:20:44 +02:00
evgeny 3c7b59ef02 Report three-run multipath rates and confirmed INIT liveness failure 2026-10-23 13:20:15 +02:00
evgeny 54fb4185f1 Identify one-way INIT liveness defect behind intermittent BGP failure 2026-10-23 13:14:51 +02:00
evgeny ac264c254c Expose transport topology in BGP route exchange failures 2026-10-23 13:13:47 +02:00
evgeny 5403647aee Record full regression results after retransmission timeout change 2026-10-23 13:05:22 +02:00
evgeny 3a007fbb29 Record jitter control and the cost of a shorter retransmission margin 2026-10-23 13:02:18 +02:00
evgeny 92e9281623 Record timeout matrix improvements and outstanding latency thresholds 2026-10-23 13:01:37 +02:00
evgeny e0f28bf851 Document reduced RTT multiplier and jitter margin for RTO 2026-10-23 12:52:59 +02:00
evgeny 9dbef48eb3 Use RTT jitter and fixed margin for ETCP retransmission timeout 2026-10-23 12:52:35 +02:00
evgeny e84e17c396 Record successful proxy burst and load validation after OOM changes 2026-10-23 12:46:10 +02:00
evgeny 9cc921f615 Record full regression failures and diagnose active media temp deletion 2026-10-23 12:45:38 +02:00
evgeny 0d5e9332e3 Clarify connection references versus active callback lifetime 2026-10-23 12:43:26 +02:00
evgeny b1e94eff34 Describe OOM session interruption and normalizer ownership precisely 2026-10-23 12:42:05 +02:00
evgeny bbe43b9842 Record completed fail-fast OOM recovery and remaining multipath work 2026-10-23 12:41:14 +02:00
evgeny 3bba05d354 Give encrypted DATA fixture a valid keepalive receive timeout 2026-10-23 12:36:20 +02:00
evgeny d43716933f Test encrypted two-sided recovery after normalizer OOM 2026-10-23 12:33:58 +02:00
evgeny 3c18e594d1 Keep the session deadline unchanged across handshake retries 2026-10-23 12:32:57 +02:00
evgeny 23d426fd0c Document fail-fast OOM and session interruption contracts 2026-10-23 12:32:56 +02:00
evgeny f221fa5a89 Exercise normalizer waiter allocation failure on a busy ETCP queue 2026-10-23 12:30:38 +02:00
evgeny 6e33675503 Verify OOM session abort, recovery and reentrant callback teardown 2026-10-23 12:29:29 +02:00
evgeny 76398d204a Add deterministic normalizer and restart fault injection hooks 2026-10-23 12:28:13 +02:00
evgeny d2b195473d Test queue discard without allocation or stale callbacks 2026-10-23 12:27:38 +02:00
evgeny caf37e9541 Make stream restart terminate explicitly if session scheduling fails 2026-10-23 12:24:48 +02:00
evgeny 316180c276 Abort normalizer sessions on OOM and guard reentrant delivery callbacks 2026-10-23 12:24:48 +02:00
evgeny 5f085b2086 Discard failed ETCP streams without allocating or replaying fragments 2026-10-23 12:22:22 +02:00
evgeny 466a56b499 Add allocation-free queue discard for terminal stream resets 2026-10-23 12:20:34 +02:00
evgeny 0989eff73d Record complete proxy integration checks and normalizer ownership fix outline 2026-10-23 11:32:10 +02:00
evgeny 187aa02b49 Record passing full regression and eight sanitizer checks 2026-10-23 11:29:53 +02:00
evgeny 0aaf6dfea0 Check metrics aggregate ACK queues and RTO state across paths 2026-10-23 11:26:45 +02:00
evgeny 9c40b489cf Record implemented multipath foundation and remaining reliability blockers 2026-10-23 11:25:13 +02:00
evgeny ce798a193e Remove stale fixture pointer and verify full transmission IDs in packet dumps 2026-10-23 11:22:37 +02:00
evgeny ddba151aa5 Adapt control metrics fixture to per-link ACK ownership 2026-10-23 11:17:20 +02:00
evgeny 2fddf839af Show transmission identity and frontier queries in ETCP packet diagnostics 2026-10-23 11:13:26 +02:00
evgeny 7bb43c42d6 Document per-path attempt ACKs, loss timers, pacing and memory bounds 2026-10-23 11:12:40 +02:00
evgeny b442d131c9 Exercise bounded attempt and ACK storage after logical delivery 2026-10-23 11:10:19 +02:00
evgeny 783646a967 Apply attempt budgets before selecting DATA paths 2026-10-23 11:09:28 +02:00
evgeny b74ff2633d Bound path ACK queues and physical attempt memory 2026-10-23 11:09:28 +02:00
evgeny b97169de19 Verify DATA pacing independently of piggyback ACK size 2026-10-23 11:04:11 +02:00
evgeny 72f48d1f14 Keep DATA pacing units consistent and test startup delay exit 2026-10-23 10:59:30 +02:00
evgeny 227104e224 Leave BBR startup after a full round of excessive queue delay 2026-10-23 10:58:38 +02:00
evgeny d57a729b92 Preserve bounded pacing credit across millisecond timer rounding 2026-10-23 10:45:39 +02:00
evgeny 3ca9926c48 Release synthetic path queues in the session-timeout fixture 2026-10-23 10:42:43 +02:00
evgeny 4c9a32d865 Observe peer-window recovery after the deferred queue resume 2026-10-23 10:40:48 +02:00
evgeny 5e436975c6 Exercise retry rotation, late attempt ACKs and receiver admission faults 2026-10-23 10:38:23 +02:00
evgeny a4a9ae7b0a Return receive-window query replies on the requesting path 2026-10-23 10:35:38 +02:00
evgeny 34a31f63be Update encrypted session fixtures and multipath observation for attempt IDs 2026-10-23 10:29:20 +02:00
evgeny 75485bf7bf Aggregate pending path ACKs in chat transport status 2026-10-23 10:28:17 +02:00
evgeny 432017cc22 Verify logical delivery and physical window counters independently 2026-10-23 10:27:38 +02:00
evgeny 147648ffd0 Expose per-path attempts and ACK queues in transport diagnostics 2026-10-23 10:25:27 +02:00
evgeny 1b3c4552fb Account for transmission IDs in MTU and packet diagnostics 2026-10-23 10:24:29 +02:00
evgeny cc510fc74c Separate stream delivery from path ACKs and acknowledge retained DATA 2026-10-23 10:23:14 +02:00
evgeny abe3d4bc89 Rotate retransmissions per fragment and commit only accepted sends 2026-10-23 10:14:46 +02:00
evgeny 7bc2ac5a46 Implement per-path attempt accounting and isolated ACK delivery samples 2026-10-23 10:13:22 +02:00
evgeny b68e0ac3db Define independent logical fragments and per-path transmission attempts 2026-10-23 10:09:44 +02:00
evgeny 3c44c3d7bc Keep unknown BBR bandwidth from imposing a one-byte pacing stall 2026-10-23 02:32:36 +02:00
evgeny e21cd26511 Apply BBR pacing through one owner and keep burst estimates diagnostic 2026-10-23 02:28:45 +02:00
evgeny 7e413db1e1 Keep pacing in bytes per second and reprice outstanding shaper debt 2026-10-23 02:28:11 +02:00
evgeny b39a861a57 Initialize STARTUP pacing from the actual initial DATA window 2026-10-23 02:24:10 +02:00
evgeny b349d7b7b2 Document agreed retransmission bounds and verified timer behavior 2026-10-23 02:21:43 +02:00
evgeny c3ac337ef0 Clamp ETCP retransmission timeout to 10 ms through 1 second 2026-10-23 02:20:10 +02:00
evgeny 4aae1f6151 Specify retry path rotation and close ACK ownership gaps 2026-10-23 02:08:04 +02:00
evgeny 259dfa35d9 Record RTT feedback experiments and refine multipath recovery plan 2026-10-23 01:56:01 +02:00
evgeny 7e0a0905e5 Document BBR queue time policy and its physical delay limits 2026-10-23 01:03:27 +02:00
evgeny 34e3d9bba0 Verify queue budget saturation and the BBR fast path contract 2026-10-23 01:02:15 +02:00
evgeny 599d8ad421 Bound BBR probe windows by the steady-state queue time budget 2026-10-23 01:01:25 +02:00
evgeny 4035794631 Define and test the BBR steady-state queue time budget 2026-10-23 01:00:36 +02:00
evgeny 5f406c2a41 Document BBR queue budget conflict with the fixed latency target 2026-10-23 00:58:29 +02:00
evgeny 94d6dd05c8 Expose BBR bandwidth and ACK budget alongside physical queue peaks 2026-10-23 00:54:27 +02:00
evgeny 67ae4ecf11 Record full regression results and reproducible NAT profile failures 2026-10-23 00:51:44 +02:00
evgeny d0f122f4d8 Record verified RTT probe fixes and remaining multipath failures 2026-10-23 00:49:02 +02:00
evgeny 08b6b2e2a1 Document DATA MSS and shared BBR transport window contracts 2026-10-23 00:45:09 +02:00
evgeny 5298fe9f6a Keep BBR loss bounds above the DATA window minimum 2026-10-23 00:43:54 +02:00
evgeny aefa8ff680 Check BBR loss bounds against the minimum DATA window 2026-10-23 00:43:31 +02:00
evgeny 0f23076f48 Apply BBR DATA windows consistently during startup and RTT probes 2026-10-23 00:42:45 +02:00
evgeny 92a535e009 Cover BBR probe drain and transport DATA window consistency 2026-10-23 00:42:02 +02:00
evgeny 519d6e4eaf Record verified BBR fixes and remaining multipath contract conflicts 2026-10-23 00:25:55 +02:00
evgeny 716db3a820 Saturate BBR byte windows instead of wrapping at large BDP 2026-10-23 00:24:35 +02:00
evgeny 3d6f855d34 Keep BBR probing and aggregation counters dimensionally consistent in bytes 2026-10-23 00:17:14 +02:00
evgeny 229e992695 Cover probing byte budgets and ACK aggregation beyond 64KiB 2026-10-23 00:16:40 +02:00
evgeny a79c724110 Grow BBR probe inflight bounds in MSS-sized byte increments 2026-10-23 00:15:46 +02:00
evgeny 6b1298aa62 Reproduce byte-sized instead of MSS-sized BBR probing growth 2026-10-23 00:15:28 +02:00
evgeny 0364abb00e Log sampled BBR model state without flooding transport diagnostics 2026-10-23 00:12:28 +02:00
evgeny f8d532b04d Describe ACK handling and bounded DATA pacing in the ETCP protocol 2026-10-23 00:10:01 +02:00
evgeny 4dba742149 Document BBR byte units and flight-based delivery rate samples 2026-10-23 00:10:00 +02:00
evgeny 88eb0f2108 Require multipath goodput without inflating channel queues 2026-10-23 00:08:15 +02:00
evgeny ade0e93f7f Measure actual channel queueing delay independently of propagation RTT 2026-10-23 00:08:15 +02:00
evgeny addff8547e Keep the ACK compression fixture within its known retransmission deadline 2026-10-23 00:06:30 +02:00
evgeny 1c18bdc9ab Measure BBR delivery over packet flights instead of inter-ACK gaps 2026-10-23 00:06:30 +02:00
evgeny f3008b7aba Snapshot delivery and send intervals for per-link BBR rate measurement 2026-10-23 00:06:30 +02:00
evgeny c2f4f048d7 Reproduce inflated delivery-rate samples when ACKs arrive together 2026-10-23 00:05:48 +02:00
evgeny 3c38072b9b Send ACK independently of the local outgoing DATA congestion pacer 2026-10-23 00:03:29 +02:00
evgeny 4cfd0ec89f Identify DATA in local datagram metadata without changing the wire header 2026-10-23 00:03:29 +02:00
evgeny 08c42e62ef Reproduce ACK starvation behind the reverse-direction DATA pacer 2026-10-23 00:02:57 +02:00
evgeny dd153264e1 Verify byte-rate scaling at multiple MTUs and multi-gigabit rates 2026-10-23 00:00:40 +02:00
evgeny 6f87ea1426 Keep BBR pacing and BDP in byte units without a second MSS factor 2026-10-22 23:59:57 +02:00
evgeny 6fec5d6d98 Reproduce MSS-dependent BBR pacing and BDP with a dimensional regression 2026-10-22 23:59:20 +02:00
evgeny 9b9a9f2e00 Record final multipath fault results and sanitizer validation 2026-10-22 23:41:45 +02:00
evgeny 27a7b7bf25 Declare the multipath phony target without overlapping Automake conditions 2026-10-22 23:40:12 +02:00
evgeny c9ba018a0d Bound fault steady goodput by newly received unique DATA 2026-10-22 23:37:24 +02:00
evgeny df5f6263bd Measure short HOLD across resume and arm faults before propagation completes 2026-10-22 23:37:02 +02:00
evgeny 0b5a892a88 Document multipath acceptance criteria and reproduced protocol limitations 2026-10-22 23:36:21 +02:00
evgeny 076016f34a Expose multipath queue accounting and add a dedicated long-running check target 2026-10-22 23:34:20 +02:00
evgeny 8417b1955c Document emulator queue bounds and account for allocation failures 2026-10-22 23:33:14 +02:00
evgeny 67322582f6 Report delivery failures per scenario without hiding subsequent channel cases 2026-10-22 23:32:34 +02:00
evgeny 439361cb52 Exclude previously buffered data from multipath utilization results 2026-10-22 23:31:02 +02:00
evgeny 6e350760d1 Check active channel stalls, delivery deadlines and delayed packet recovery 2026-10-22 23:29:29 +02:00
evgeny 672f04b833 Exercise real ETCP multipath against independent bandwidth and RTT profiles 2026-10-22 23:23:05 +02:00
evgeny f5cab5a14e Calibrate dummynet bandwidth and verify stalled channel lifecycle 2026-10-22 23:19:01 +02:00
evgeny f5f6ff50af Make dummynet bandwidth timing cumulative and add bounded DROP/HOLD modes 2026-10-22 23:18:11 +02:00
evgeny 62f4850968 Record successful full ETCP regression validation 2026-10-22 23:04:00 +02:00
evgeny 082d9d3960 Record STCP SIGPIPE regression and sanitizer validation 2026-10-22 23:02:42 +02:00
evgeny 05a5b6c2a7 Exercise STCP writes with default SIGPIPE disposition 2026-10-22 22:59:45 +02:00
evgeny fdcf92be04 Prevent SIGPIPE from terminating embedded STCP transports 2026-10-22 22:59:44 +02:00
evgeny 11aa760d47 Document ETCP window ownership and completed connection fixes 2026-10-22 22:57:06 +02:00
evgeny bc27352710 Remove stale references to the legacy connect installer 2026-10-22 22:53:55 +02:00
evgeny 0a00bd1c90 Clarify readiness contracts and stop on corrupt accounting 2026-10-22 22:53:30 +02:00
evgeny e2ee0d81dd Wait for both ETCP streams before starting Merkle tests 2026-10-22 22:52:14 +02:00
evgeny 6afc57569a Test zero-delay sender wakeups and failure injection 2026-10-22 22:50:38 +02:00
evgeny ccb3821e2f Schedule ordinary ETCP sends without timer latency 2026-10-22 22:50:04 +02:00
evgeny 29f9a97552 Use valid global options in REALITY config fixtures 2026-10-22 22:48:53 +02:00
evgeny f37ac2c637 Verify deferred teardown when the TX timer cannot start 2026-10-22 22:47:50 +02:00
evgeny 0ef0553598 Coalesce useful TX wakeups and defer failure teardown safely 2026-10-22 22:45:58 +02:00
evgeny f1c88ad375 Document congestion configuration and protect key diagnostics 2026-10-22 22:40:47 +02:00
evgeny 17c92e1745 Diagnose adopted transports and isolate traffic test commands 2026-10-22 22:39:43 +02:00
evgeny 34e346463d Cover initial UP, pacing and bidirectional tight windows 2026-10-22 22:38:20 +02:00
evgeny ef11d3b677 Preserve initial readiness while sender waits for a session 2026-10-22 22:36:53 +02:00
evgeny 2689931826 Inject allocation failures through the actual pool symbol 2026-10-22 22:34:07 +02:00
evgeny 133ea8d120 Wake sender after preparing each new fragment 2026-10-22 22:33:43 +02:00
evgeny 75ff7c4ce3 Exercise DATA windows, ACKs, retries and sender wakeups 2026-10-22 22:33:11 +02:00
evgeny 86a0f041c7 Validate congestion limits and guard window arithmetic 2026-10-22 22:31:12 +02:00
evgeny c1f07ec6ae Enforce per-link DATA windows without blocking ACKs 2026-10-22 22:29:31 +02:00
evgeny 50d5486a9f Define per-link accounting and deferred sender contracts 2026-10-22 22:26:51 +02:00
evgeny 036cf43918 Build and document direct connections through NCD 2026-10-22 22:25:52 +02:00
evgeny fc5b3911f3 Detach ETCP core from obsolete connect contexts 2026-10-22 22:25:39 +02:00
evgeny 008f499367 Remove obsolete parallel ETCP connection installer 2026-10-22 22:25:39 +02:00
evgeny 8169322d56 Move direct transport tests to NCD ownership 2026-10-22 22:24:45 +02:00
evgeny d84ab69465 Verify link selection mismatch with valid congestion limits 2026-10-22 21:32:34 +02:00
evgeny 91bb95a981 Record ETCP and STCP header audit findings 2026-10-22 21:30:28 +02:00
evgeny 03f4cd7939 Record validated media supernode replication implementation 2026-10-22 21:21:43 +02:00
evgeny 71d3b017e6 Clarify local media catalog seeding and channel cleanup contracts 2026-10-22 21:20:21 +02:00
evgeny 8230eb4de7 Test final-page update races and replication read failures 2026-10-22 21:16:59 +02:00
evgeny bc149497f3 Document media replication protocol and resource ownership 2026-10-22 21:15:55 +02:00
evgeny 0bcdb9930a Make media send queue policy explicit and document announcement errors 2026-10-22 21:14:42 +02:00
evgeny f2283eff6b Wait for actual retry requests independently of change hints 2026-10-22 21:12:58 +02:00
evgeny a011c57237 Cover replication retries, source reset and router backpressure 2026-10-22 21:10:44 +02:00
evgeny 9e2a1e5208 Handle automatic SQLite rollback and complete CHAT integration setup 2026-10-22 21:09:16 +02:00
evgeny d6d8ffc4a8 Require role subscription and initialize real chat test contexts 2026-10-22 21:07:18 +02:00
evgeny 14b01964b1 Initialize media test dependencies and await committed sync 2026-10-22 21:06:15 +02:00
evgeny 7fb9b43e9e Validate media role changes through signed CHAT membership 2026-10-22 21:02:57 +02:00
evgeny 63c0b9a655 Run media integration replication in its actual CHAT group 2026-10-22 21:01:24 +02:00
evgeny 00502bf4d4 Exercise real media replication pages, rollback and catalog lifecycle 2026-10-22 21:00:48 +02:00
evgeny d3bc77922b Initialize replication router queues before waiting for room 2026-10-22 20:55:25 +02:00
evgeny b4b11d6086 Implement atomic group-scoped media catalog replication 2026-10-22 20:54:37 +02:00
evgeny b47a82e3ac Define bounded receiver-driven media replication protocol 2026-10-22 20:45:14 +02:00
evgeny 04dc53672a Add regression for media availability group isolation 2026-10-22 20:43:51 +02:00
evgeny 964a938437 Record reproduced media replication failures and correct cursor audit 2026-10-22 20:11:06 +02:00
evgeny e8843d9499 Track remaining media supernode replication audit separately 2026-10-22 19:53:31 +02:00
evgeny ecba318dec Record validated media block ownership and relay fixes 2026-10-22 19:48:47 +02:00
evgeny 1aec478787 Drive relay generation wakeup through actual queue consumption 2026-10-22 19:46:30 +02:00
evgeny 8f97cf8070 Verify old relay readers survive a new download generation independently 2026-10-22 19:45:45 +02:00
evgeny bd0260040c Replace obsolete media relay description with current attempt and buffer contracts 2026-10-22 19:43:59 +02:00
evgeny 3b24e7e207 Describe media source lifetime, callback ownership and publication ordering 2026-10-22 19:40:38 +02:00
evgeny 993e22085a Scope libc fault-injection regression target to Linux 2026-10-22 19:39:34 +02:00
evgeny 00e0421e56 Update media wire-size assertions and cover fortified read fault injection 2026-10-22 19:38:56 +02:00
evgeny fabeb770a7 Verify media source admission, redirect bounds and transmit I/O failure cleanup 2026-10-22 19:37:28 +02:00
evgeny 47addfeffc Cover terminal media registration failures and relay admission lifetime 2026-10-22 19:35:45 +02:00
evgeny 02e1526115 Remove redundant embedded download entry and update service-stop request 2026-10-22 19:33:49 +02:00
evgeny c81cc8b9ca Document media attempt validation and reserve before tracking outgoing writes 2026-10-22 19:33:12 +02:00
evgeny 99389f4bd3 Bound relay readers independently and redirect only to matching block recipients 2026-10-22 19:32:15 +02:00
evgeny b09a020855 Exercise media block identity, I/O failure, reentrancy and relay backpressure 2026-10-22 19:30:59 +02:00
evgeny 090e7db598 Expose transport queue control in media regression fixtures 2026-10-22 19:27:37 +02:00
evgeny 5215163a37 Share authenticated media fixtures for adversarial delivery regressions 2026-10-22 19:25:24 +02:00
evgeny 1c1ab24a27 Test real truncated-block assembly and balance media admission ownership 2026-10-22 19:24:17 +02:00
evgeny 353752165c Align media integration inputs with routed block identity 2026-10-22 19:23:53 +02:00
evgeny b1a3d0c6cd Scope media retry responses to active block attempts 2026-10-22 19:17:36 +02:00
evgeny 16333b989d Replace permissive media download fixtures with verified block inputs 2026-10-22 19:16:23 +02:00
evgeny d2bf40e11a Use authenticated block metadata in media query fixtures 2026-10-22 19:15:17 +02:00
evgeny d0a401e166 Validate received blocks and publish complete verified media atomically 2026-10-22 19:14:12 +02:00
evgeny 4edf72ea14 Create independent block attempts and cancel channel downloads safely 2026-10-22 19:11:44 +02:00
evgeny 9b4974f02d Unify media source and relay transmission with owned buffers 2026-10-22 19:11:26 +02:00
evgeny f15d53947e Define media block attempts and shared byte-source ownership 2026-10-22 19:08:14 +02:00
evgeny 68129c0151 Retain media downloads across reentrant progress callbacks 2026-10-22 19:07:04 +02:00
evgeny a3a8b5b1be Add checked UTF-8 opening of existing block files for update 2026-10-22 19:03:16 +02:00
evgeny 55d2f437a0 Clarify ownership requirements for media completion callbacks 2026-10-22 18:57:48 +02:00
evgeny 108dfae82b Record reproduced media block receive and completion defects 2026-10-22 18:45:19 +02:00
evgeny 3a703d1093 Record final media QUERY full-suite validation 2026-10-22 18:31:13 +02:00
evgeny 433a091db5 Record verified media QUERY fixes and regression coverage 2026-10-22 18:31:13 +02:00
evgeny 21ebc832e1 Verify holder selection and log download resource transitions 2026-10-22 18:31:12 +02:00
evgeny a3f3b2fff2 Document media lookup lifetimes and remove obsolete shared state 2026-10-22 18:31:12 +02:00
evgeny 093e537fed Check live QUERY deadlines and deferred CM failover 2026-10-22 18:31:12 +02:00
evgeny 6a14be05f5 Verify second-block SQL failure and propagate local download errors 2026-10-22 18:31:12 +02:00
evgeny fd6155aa4a Exercise media QUERY bounds, paging, failures and peer reuse 2026-10-22 18:31:12 +02:00
evgeny f47e80571d Assert media QUERY results and preserve transport ownership in tests 2026-10-22 18:31:12 +02:00
evgeny e02c9f7727 Cancel delayed CM UP before deferring failover 2026-10-22 18:31:12 +02:00
evgeny 05ace58589 Implement bounded media lookup with independent deadlines 2026-10-22 18:31:12 +02:00
evgeny 92c514ce18 Describe bounded media lookup and peer slot state 2026-10-22 18:31:12 +02:00
evgeny 6267973d62 Define bounded media QUERY batches and complete responses 2026-10-22 18:31:12 +02:00
evgeny cecbc682a0 Move stream start and stop into the title bar 2026-10-22 18:13:43 +02:00
evgeny 07cd150b47 Merge shared Android media audio routing and microphone fixes 2026-10-22 18:04:49 +02:00
evgeny 6a1c289ab2 Keep Bluetooth SCO active for radio reception without capture 2026-10-22 17:59:11 +02:00
evgeny bb380441a3 Fix shared microphone crackle from timestamp jitter 2026-10-22 16:53:25 +02:00
evgeny 94d1e245a5 Record reproduced media QUERY bounds and response truncation defects 2026-10-22 16:47:28 +02:00
evgeny 02265644ce Record verified media index fixes and remaining QUERY audit 2026-10-22 15:48:15 +02:00
evgeny c9a3a1334b Restore shared media playback to speaker after headset loss 2026-10-22 15:24:13 +02:00
evgeny 0835c3d3cc Describe media preparation records and deferred channel cleanup 2026-10-22 15:15:52 +02:00
evgeny 34959a9657 Share atomic media commits between downloads and backfill 2026-10-22 15:14:25 +02:00
evgeny 90fab54a4a Use one atomic commit API for authored and downloaded files 2026-10-22 15:14:22 +02:00
evgeny 439011ce60 Use real media schema and validate duplicate download ownership 2026-10-22 15:13:14 +02:00
evgeny ec70908733 Check relative path limits and binding failures without truncation 2026-10-22 15:11:23 +02:00
evgeny 2b63c680b2 Verify shared Android audio ownership on a physical device 2026-10-22 15:07:26 +02:00
evgeny 44a3b33c3a Expose shared audio devices in stream viewing and document them 2026-10-22 15:07:26 +02:00
evgeny 5d10a16baa Use shared audio controls in radio and stream publication 2026-10-22 15:07:25 +02:00
evgeny 33ccba1f3f Add a common audio device selector for radio and streams 2026-10-22 15:07:25 +02:00
evgeny bebc579180 Share media playback devices and await cleanup before calls 2026-10-22 15:07:25 +02:00
evgeny a893f6b4f2 Route radio and stream capture through the shared controller 2026-10-22 15:07:25 +02:00
evgeny ecada765a2 Own Android media devices in one shared audio controller 2026-10-22 15:07:25 +02:00
evgeny b72e51accb Keep shared microphone PCM continuous across device changes 2026-10-22 15:07:25 +02:00
evgeny f123a1bdeb Document preparation ownership and log exact media index failures 2026-10-22 15:06:00 +02:00
evgeny 3bb8f76b7d Reuse the database media base when restarting chat 2026-10-22 15:03:41 +02:00
evgeny 6b54b63986 Define download start ownership and avoid access after completion 2026-10-22 15:00:41 +02:00
evgeny c08c24140c Test reentrant media events and cleanup after hash failure 2026-10-22 14:58:15 +02:00
evgeny d4efdba44e Retain failed download destinations for later cleanup 2026-10-22 14:56:07 +02:00
evgeny 41057ee9d5 Keep media task ownership through synchronous submission events 2026-10-22 14:54:18 +02:00
evgeny 87724433b1 Exercise media index failure recovery and pending channel deletion 2026-10-22 14:52:27 +02:00
evgeny 9117813c4d Preserve indexed and unfinished files during orphan cleanup 2026-10-22 14:49:11 +02:00
evgeny 15fafc42c9 Use validated paths for media submission and backfill 2026-10-22 14:46:49 +02:00
evgeny 16a5e628fd Report incomplete media cleanup separately from channel deletion 2026-10-22 14:46:15 +02:00
evgeny 32d80110cb Drain outgoing media tasks before deleting their channel 2026-10-22 14:45:29 +02:00
evgeny b3a223521c Track unfinished media destinations for channel cleanup 2026-10-22 14:44:24 +02:00
evgeny 8cba8ef3e6 Propagate media schema and downloaded registration failures 2026-10-22 14:42:44 +02:00
evgeny 113f0259ea Preserve retryable media cleanup and validate served paths 2026-10-22 14:41:45 +02:00
evgeny 889dfc411a Validate media paths and register complete files atomically 2026-10-22 14:40:30 +02:00
evgeny ad62eee10c Record media index plan constraints and late completion race 2026-10-22 14:35:56 +02:00
evgeny d68ab90f23 Record reproduced media index path and database failures 2026-10-22 14:26:49 +02:00
evgeny ad0505bd31 Record verified media primitive fixes and remaining location audit 2026-10-22 13:40:39 +02:00
evgeny 64519c41a7 Restrict fortified stdio test hook to glibc 2026-10-22 13:35:25 +02:00
evgeny 0d55c98add Inject fortified fread failures in sanitizer regressions 2026-10-22 13:34:54 +02:00
evgeny 5549a69b1c Cover failed file stream creation and document media cancellation effects 2026-10-22 13:31:13 +02:00
evgeny 1ceb0beb8d Check generated media identifiers in integration fixtures 2026-10-22 10:28:32 +02:00
evgeny 386ea85fea Log precise copy and media indexing failure operations 2026-10-22 10:27:42 +02:00
evgeny 607de2a074 Bound recursive walker stack and report exact copy failure phases 2026-10-22 10:26:56 +02:00
evgeny bf3834b95d Use existing Linux condition for media fault injection 2026-10-22 10:24:16 +02:00
evgeny 3a00caef50 Add fault injection regressions for media files and worker ownership 2026-10-22 10:23:56 +02:00
evgeny 5505afd1f3 Keep thumbnail path bounds and check UUID status in stress test 2026-10-22 10:21:41 +02:00
evgeny 0e418c7fa9 Propagate RNG errors and preserve 64-bit media sizes through callers 2026-10-22 10:20:02 +02:00
evgeny f399ded5ba Preserve files on copy errors and check media primitive failures 2026-10-22 10:18:23 +02:00
evgeny 85d96fc857 Share UTF-8 Windows path conversion with file workers 2026-10-22 10:18:22 +02:00
evgeny 3100985e4c Specify media worker ownership errors and primitive contracts 2026-10-22 10:16:57 +02:00
evgeny 6355bd1d73 Use shared file publication in video processing 2026-10-22 10:15:39 +02:00
evgeny 3ed4b73ebf Extract checked file identity and temporary publication primitives 2026-10-22 10:15:13 +02:00
evgeny 41cc04bdab Record media async primitive and contract audit findings 2026-10-22 10:07:20 +02:00
evgeny d8621c7f27 Record bootstrap regression coverage and successful validation 2026-10-22 10:02:57 +02:00
evgeny 3c49c2a4aa Initialize callback epoch for pending transport shutdown test 2026-10-22 09:59:13 +02:00
evgeny 633f1d3044 Schedule pending deadline resets from probe creation 2026-10-22 09:47:23 +02:00
evgeny 34602e3e7e Separate cold bootstrap from controlled pending probe reset 2026-10-22 09:45:48 +02:00
evgeny 330e346a7b Record bootstrap test race in TCP session initialization 2026-10-22 09:40:08 +02:00
evgeny 6d39800351 Record completed video fixes and validation coverage 2026-10-22 00:20:40 +02:00
evgeny df2f90d1f5 Allow MP4 millisecond edit rounding in audio tail regression 2026-10-22 00:17:55 +02:00
evgeny 1d6596dc61 Check resampler tail duration and actual 1080p to 720p conversion 2026-10-22 00:17:16 +02:00
evgeny 0653121fc4 Document video publication and cancellation in service lifecycle 2026-10-22 00:15:54 +02:00
evgeny 3f603534e9 Log exact video failure phases and check buffered file seeks 2026-10-22 00:11:02 +02:00
evgeny 631cc924cf Measure AAC signal onset above verified codec pre-echo level 2026-10-22 00:09:49 +02:00
evgeny 9f1825dbf8 Verify decoded video content, AAC signal timing and FFmpeg-free stubs 2026-10-22 00:08:22 +02:00
evgeny 9163025912 Test video I/O failures, audio timing, cancellation and concurrent ownership 2026-10-22 00:05:30 +02:00
evgeny 5929bb4028 Normalize unspecified PCM channel layouts before AAC setup 2026-10-22 00:03:12 +02:00
evgeny fe313cf8f8 Match FFmpeg AVIO and codec capability APIs across supported versions 2026-10-22 00:02:29 +02:00
evgeny cb9102f381 Prepare video through checked temporary output and complete codec drains 2026-10-22 00:01:47 +02:00
evgeny 9a8bc9b461 Select video regression branch from configured FFmpeg support 2026-10-21 23:59:06 +02:00
evgeny c4bf292085 Specify video publication, remux and completion contracts 2026-10-21 23:58:55 +02:00
evgeny 8d9704036f Add real video fixtures and file preservation regressions 2026-10-21 23:56:55 +02:00
evgeny fb01a9bb2e Record video audit failures and missing API contracts 2026-10-21 23:28:53 +02:00
evgeny 1d7e12c562 Avoid random HEX substring collisions in config updater assertions 2026-10-21 23:12:12 +02:00
evgeny 7c473dd500 Reject signed NAT forward IDs hidden by leading whitespace 2026-10-21 23:11:32 +02:00
evgeny 1ccb266971 Describe NAT transport backpressure, ownership and mapping holds 2026-10-21 23:08:31 +02:00
evgeny 7de54ab3e4 Document NAT hash, expiry, mapping holds and bounded transport ownership 2026-10-21 22:58:28 +02:00
evgeny 2c10272e15 Add repeatable NAT benchmarks for table size, payload size and full-pool misses 2026-10-21 22:55:24 +02:00
evgeny 55cc721c9b Test held NAT mappings under TUN congestion and reject invalid provider input 2026-10-21 22:54:24 +02:00
evgeny dea768c21a Hold outgoing NAT mappings through asynchronous TUN delivery 2026-10-21 22:52:19 +02:00
evgeny 824c663ebd Protect NAT mappings referenced by pending TUN transmissions 2026-10-21 22:51:25 +02:00
evgeny 80b481827c Verify bounded global NAT pressure and retained destination across mapping reuse 2026-10-21 22:46:09 +02:00
evgeny 8360e48622 Exercise NAT backpressure, mapping reuse, copy ownership and shutdown 2026-10-21 22:44:46 +02:00
evgeny 41a68b86bc Close NAT channels after cancelling producers and quiet transient TUN backpressure 2026-10-21 22:43:54 +02:00
evgeny cfc0051088 Test NAT boundary validation, hash collisions, expiry and allocation failures 2026-10-21 22:34:06 +02:00
evgeny cecc5d7d1f Validate provider replies before client TUN delivery 2026-10-21 22:32:29 +02:00
evgeny 5e2e6c15cf Preserve NAT index invariants across transport and reuse tests 2026-10-21 22:31:55 +02:00
evgeny d0c83cfff1 Add bounded NAT backpressure and forward TUN packets without copying 2026-10-21 22:30:01 +02:00
evgeny 9d6d6454b0 Reject malformed NAT configuration and use mapping lifecycle APIs in tests 2026-10-21 22:27:16 +02:00
evgeny 94fa3207f6 Index NAT mappings by hash and maintain free ports in constant time 2026-10-21 22:24:17 +02:00
evgeny 5a837f903c Validate NAT packet boundaries and distinguish skipped packets 2026-10-21 22:21:37 +02:00
evgeny 00b4b92749 Align NAT documentation with node ownership and router framing 2026-10-21 22:01:08 +02:00
evgeny 19a5870d5f Document NAT ownership, packet formats and API contracts 2026-10-21 22:00:06 +02:00
evgeny bfa23afae9 Restrict NAT delivery to its group and configured provider 2026-10-21 21:58:10 +02:00
evgeny 909005c1a4 Complete standalone NAT forward configuration fixture 2026-10-21 21:57:23 +02:00
evgeny ddc163a2b7 Cover NAT forward owners, full port range and invalid rules 2026-10-21 21:56:20 +02:00
evgeny ca471d777e Route static NAT forwards to explicit owners on all ports 2026-10-21 21:55:13 +02:00
evgeny 2c4f107e63 Require a target node for NAT port forward configuration 2026-10-21 21:54:41 +02:00
evgeny 3d0c4ff0a5 Isolate NAT mappings by source node identity 2026-10-21 21:53:17 +02:00
evgeny a9820bea42 Preserve IPv4 UDP checksum encoding through NAT 2026-10-21 21:51:49 +02:00
evgeny 52a73ea6a7 Correct incremental NAT checksum arithmetic 2026-10-21 21:50:59 +02:00
evgeny 6e9bacd843 Fix NAT flow lookup at the maximum port boundary 2026-10-21 21:48:28 +02:00
evgeny fbbd62acc4 Fix NAT packet ownership after router send failures 2026-10-21 21:43:00 +02:00
evgeny ef673eb3b7 Merge branch 'master' of http://git.syqiq.tech/jeka/utun2 2026-10-21 21:22:49 +02:00
evgeny 05b0927619 Fix TUN packet ownership, lifecycle and backend consistency
Unify TUN initialization and raw-IP writes, preserve socketpair directions, and bound reader delivery with queue backpressure. Make deferred packet ownership safe across close and uasync teardown, and apply per-interface MTU limits to lwIP MSS.

Validation: full check.sh passed 172 tests, 9 proxy integration checks, burst and load. TUN ASAN/UBSAN regressions passed 30 cases; TCP exchange passed with asymmetric and minimum MTUs. Sanitized NAT integration exposed an existing unaligned uint16_t read in eim_nat.c; that separate defect remains unchanged. Native Windows and FreeBSD validation remains outstanding.
2026-10-21 21:19:42 +02:00
evgeny e3f2feb480 Merge branch 'master' of http://git.syqiq.tech/jeka/utun2 2026-10-21 20:26:26 +02:00
evgeny a65b0c8786 Fix queue extraction in NTP regression cleanup 2026-10-21 20:18:49 +02:00
evgeny 6c84e680af Improve NTP failure diagnostics and source transition coverage 2026-10-21 20:18:17 +02:00
evgeny d6eed66926 Document NTP contracts and verify corrected wall time 2026-10-21 20:16:38 +02:00
evgeny 88bf65e07d Cover NTP correction, retries, faults and peer lifecycle 2026-10-21 20:15:17 +02:00
evgeny 13c1831baa Fix peer time cache ownership and callback teardown 2026-10-21 20:12:04 +02:00
evgeny 5609d57947 Fix NTP offset and bound asynchronous polling cycles 2026-10-21 20:11:04 +02:00
evgeny 488be0edd1 Record recurring attachment test timeout during control validation 2026-10-21 20:06:51 +02:00
evgeny e620567804 Finalize control server regression fixture cleanup 2026-10-21 20:04:30 +02:00
evgeny fdf2912427 Cover control server regressions and correct API documentation 2026-10-21 20:04:30 +02:00
evgeny 51922cd18e Fix control server buffer bounds and client resource ownership 2026-10-21 20:04:19 +02:00
evgeny 79946bb07c Keep firewall reload regression on the selective path 2026-10-21 20:00:28 +02:00
evgeny 41c32cf063 Set router packet length in firewall integration fixture 2026-10-21 19:59:34 +02:00
evgeny 4f627bddff Align firewall examples with symmetric destination filtering 2026-10-21 19:53:50 +02:00
evgeny 2a2a0ee267 Cover firewall parsing, bidirectional TUN filtering and reload failures 2026-10-21 19:52:51 +02:00
evgeny 5de0eb5115 Filter both directions of the main TUN and remove obsolete firewall guide 2026-10-21 19:49:32 +02:00
evgeny cf6c3c99e8 Reject invalid firewall configuration and preserve policy on reload failure 2026-10-21 19:48:54 +02:00
evgeny c3a7f77b54 Make firewall rule replacement atomic and validate IPv4 packets 2026-10-21 19:48:19 +02:00
evgeny 4f5651906c Report precise INI read failures and identity repair reasons 2026-10-21 19:09:03 +02:00
evgeny 2df21efc22 Bound edited INI growth and cover effective duplicate values 2026-10-21 19:06:59 +02:00
evgeny b0f5055c31 Describe shared INI parsing and distribute its internal header 2026-10-21 19:04:54 +02:00
evgeny 80eb331d6a Document config identity and publication guarantees 2026-10-21 19:04:53 +02:00
evgeny bb87a0845b Verify config updates preserve files and allocations under OOM 2026-10-21 19:03:39 +02:00
evgeny f7c8b95af6 Bound INI buffers to allocator limits and log allocation errors 2026-10-21 19:03:38 +02:00
evgeny 33130c1d74 Test identity preservation and failed config publication 2026-10-21 19:02:20 +02:00
evgeny f61c0c3e38 Preserve config identity and publish verified updates safely 2026-10-21 19:00:06 +02:00
evgeny 2410c39b71 Share INI parsing and validate complete configuration values 2026-10-21 18:54:43 +02:00
evgeny 5a57b59b50 Test emulator forwarding and partial initialization cleanup 2026-10-21 18:14:03 +02:00
evgeny ff3eb02bff Update emulator uasync lifecycle and document forwarding rules 2026-10-21 18:12:06 +02:00
evgeny 56d5fcd75a Test broadcast UUID lifetime and callback registration contracts 2026-10-21 18:10:43 +02:00
evgeny 484b620016 Preserve broadcast UUIDs until TTL and document callback contracts 2026-10-21 18:08:50 +02:00
evgeny 16f81575ce Consolidate TCP queue and resource lifecycle documentation in header 2026-10-21 17:59:08 +02:00
evgeny 10b039686c Consolidate queue usage and backpressure documentation in header 2026-10-21 17:57:34 +02:00
evgeny 194bf7bb45 Consolidate debug configuration documentation in header 2026-10-21 17:56:13 +02:00
evgeny a288afd8ce Consolidate socket lifecycle and wrapper documentation in header 2026-10-21 17:55:27 +02:00
evgeny 4f3f6d3e60 Consolidate platform adapter documentation in header 2026-10-21 17:55:27 +02:00
evgeny 1c4010ebed Consolidate serialization format and ownership documentation in header 2026-10-21 17:54:20 +02:00
evgeny ace9cb70d0 Consolidate timeout heap ownership and complexity documentation 2026-10-21 17:54:20 +02:00
evgeny af3c7a4217 Consolidate pool lifecycle and diagnostics documentation in header 2026-10-21 17:53:00 +02:00
evgeny e403a2f689 Consolidate memory ownership and allocation documentation in header 2026-10-21 17:53:00 +02:00
evgeny 3944459c29 Consolidate sliding minimum documentation in header 2026-10-21 17:52:02 +02:00
evgeny 48383ef95e Consolidate outgoing IP documentation in header 2026-10-21 17:52:02 +02:00
evgeny f020a6f62b Clarify CPU indicator polling and pending responses 2026-10-21 17:48:35 +02:00
evgeny d23a96a08e Document uasync scheduling, ownership and lifecycle contracts 2026-10-21 17:40:20 +02:00
evgeny dffcd19d21 Clarify queue callback scheduling and ownership contracts 2026-10-21 17:27:04 +02:00
evgeny 9079ab5c24 Fix debug timestamps, default output and log reopening 2026-10-21 17:10:44 +02:00
evgeny 7e39f16e0f Fix allocation size overflow, zero-size OOM and debug category parsing 2026-10-21 17:07:11 +02:00
evgeny 00819654cf Document POSIX descriptor zero exception in socket close 2026-10-21 16:57:44 +02:00
evgeny 346c06f31d Record TCP lifecycle validation and IPv6 selection caveat 2026-10-21 16:52:11 +02:00
evgeny ba7c2873c5 Initialize proxy timers before notifying connected owners 2026-10-21 16:48:25 +02:00
evgeny 0e15234ce1 Clarify TCP lifecycle and platform address selection contracts 2026-10-21 16:46:45 +02:00
evgeny e5fafacf99 Cover TCP timer replacement failures and pending FIN cleanup 2026-10-21 16:45:53 +02:00
evgeny d467d3aa8f Fix TCP connect timer ownership and pending FIN state 2026-10-21 16:44:19 +02:00
evgeny d5e489598d Clarify DNS lifetimes and parser and video plane limits 2026-10-21 16:33:16 +02:00
evgeny 1ff02188ca Fix Silero model cleanup and document runtime configuration 2026-10-21 16:29:44 +02:00
evgeny f31b34d0f0 Clarify serialization limits, cleanup and error codes 2026-10-21 16:18:51 +02:00
evgeny ecd5b9fc9d Clarify memory pool counters and strbuf error documentation 2026-10-21 16:14:48 +02:00
evgeny aca6364378 Correct call routing, media channels and API documentation 2026-10-21 16:11:36 +02:00
evgeny 88e930cc0a docs: correct member file protocol and media download contracts 2026-10-21 16:01:30 +02:00
evgeny be235e01aa docs: correct DM payload, history and transfer cancellation contracts 2026-10-21 15:53:28 +02:00
evgeny 66f004f725 docs: describe actual DM identity derivation and crypto modules 2026-10-21 15:52:45 +02:00
evgeny cbe22899c2 docs: align chat invite and member sync descriptions with code 2026-10-21 15:47:56 +02:00
evgeny df36e504fc docs: remove completed and obsolete project tasks 2026-10-21 15:47:30 +02:00
evgeny 7c814f5cb9 Route desktop codec diagnostics through the shared log
Quiet capability probes, preserve runtime errors, and register the desktop portal application. Add logging and desktop launcher regression coverage.
2026-10-21 15:45:40 +02:00
evgeny 9ba78c084b docs: correct topology API and router timeout descriptions 2026-10-21 15:40:56 +02:00
evgeny d644126cac docs: align ETCP handshake and epoch descriptions with code 2026-10-21 15:37:01 +02:00
evgeny f59f64ea48 docs: remove reviewed header backup files 2026-10-21 15:22:42 +02:00
evgeny f5f106c682 docs: clarify header APIs and preserve originals in .h1 2026-10-21 15:21:27 +02:00
evgeny abf342534f Encrypt P2P call media and validate service IDs
Require signed and encrypted call audio/video using static identity keys. Fix attachment service ID collisions and media download handle lifetime; isolate LAN tests and audit the shared service registry.
2026-10-21 15:06:27 +02:00
evgeny 8e46cf9254 docs: refresh project file descriptions in AGENTS.md 2026-10-21 14:54:06 +02:00
evgeny 15b037aef7 Scroll to latest chat messages with End key 2026-10-21 13:31:50 +02:00
evgeny 69e534304b Darken desktop chat backgrounds and lighter panels 2026-10-21 13:26:05 +02:00
evgeny 4dbc543cd3 Increase contrast of chat scrollbar thumb only 2026-10-21 13:21:30 +02:00
evgeny 4f6808156f Add chat history keyboard scrolling and remove unused PTT setting 2026-10-21 13:05:31 +02:00
evgeny 5870efdf04 Default stream redundancy to zero on Android and desktop 2026-10-21 12:42:23 +02:00
evgeny 34db81c5cf Show green stream watch buttons only for active streams 2026-10-21 12:30:08 +02:00
evgeny a31436e421 Expand chat README and add stream image 2026-10-21 02:31:00 +02:00
evgeny 550f384c69 Tidy stream video worker source formatting 2026-10-21 01:40:04 +02:00
evgeny a6b909b70e Add device regression for independent stream audio and video workers 2026-10-21 01:38:50 +02:00
evgeny fcb0768052 Protect SoundTouch lookahead when catching up live stream audio 2026-10-21 01:38:50 +02:00
evgeny 5d9da0c6b1 Preserve exact source EOF across tempo changes and expose DSP lookahead 2026-10-21 01:38:50 +02:00
evgeny e8ee608ba9 Document independent audio preparation and live stream catchup 2026-10-21 01:28:20 +02:00
evgeny 4e5530aca0 Isolate Android live video decoding from audio preparation 2026-10-21 01:23:35 +02:00
evgeny 4fa3b18cc2 Feed Android stream mixer from prepared PCM without holding DSP lock 2026-10-21 01:18:56 +02:00
evgeny 50cf61e9cd Mix partial stream PCM without copying stale buffer tails 2026-10-21 01:11:35 +02:00
evgeny c6ed01110e Exercise audio continuity during video stalls and generation changes 2026-10-21 01:03:19 +02:00
evgeny 1764603977 Isolate live video decoding from audio preparation in ChatGUI 2026-10-21 01:00:31 +02:00
evgeny 6c619d5f2a Recover stream playback stalls with bounded proportional catchup 2026-10-21 00:56:47 +02:00
evgeny 58c0fc6bba Separate stream audio DSP from bounded PCM consumption 2026-10-21 00:54:30 +02:00
evgeny 32e648ea9e Release audio holds at video EOF and stop Android batches promptly 2026-10-21 00:15:34 +02:00
evgeny b2efab9806 Document per-track completion and Android batch wakeups 2026-10-21 00:13:01 +02:00
evgeny a342316e7a Verify delayed decoders with unequal audio and video tails 2026-10-21 00:13:01 +02:00
evgeny c887780022 Consume Android batches with independent track completion 2026-10-21 00:13:01 +02:00
evgeny a538f99bf0 Expose viewer wake signals and complete audio independently on Android 2026-10-21 00:13:01 +02:00
evgeny 9fb4823df0 Batch Android viewer records and wake readers on data or stop 2026-10-21 00:13:01 +02:00
evgeny a2fb562a22 Drain desktop tracks independently and cancel obsolete media on reset 2026-10-20 23:54:55 +02:00
evgeny 852c05590d Expose track completion to desktop and retain the longer media tail 2026-10-20 23:53:58 +02:00
evgeny a54031081b Deliver independent track ends and invalidate batches on gaps 2026-10-20 23:53:23 +02:00
evgeny 23c4e4efbc Diagnose delayed decoder completion with buffered audio 2026-10-20 23:46:59 +02:00
evgeny 5bc0c1ece4 Document bounded desktop stream batches and worker wakeups 2026-10-20 23:42:28 +02:00
evgeny fbab6eae5d Anchor batch regression at a single initial keyframe 2026-10-20 23:41:12 +02:00
evgeny 0d9c728efe Test bounded batches, track budgets, notifications and FIN 2026-10-20 23:34:57 +02:00
evgeny 039c4a9ed4 Consume desktop media batches with per-track backpressure and wakeups 2026-10-20 23:31:50 +02:00
evgeny 179f248db8 Deliver bounded media batches to desktop consumers 2026-10-20 23:30:10 +02:00
evgeny 589cdcc81f Add bounded viewer batches and readiness notifications 2026-10-20 23:29:23 +02:00
evgeny 6997a82af1 Enable publisher timing logs in diagnostic test runs 2026-10-20 22:32:33 +02:00
evgeny c6f7d50838 Measure stream viewer request and worker delays 2026-10-20 22:30:04 +02:00
evgeny 7ce60ca0f2 Trace desktop stream stalls across playback and preview UI 2026-10-20 22:20:31 +02:00
evgeny b1112981fa Timestamp Android decoder output at the observation point 2026-10-20 21:44:10 +02:00
evgeny a4419b4c89 Validate Android surface timestamps in stream diagnostics 2026-10-20 21:40:20 +02:00
evgeny 1b036e4ea9 Trace stream startup decoding and presentation delays 2026-10-20 21:34:24 +02:00
evgeny f38aa3b08d Log stream startup key age and buffer handoff delays 2026-10-20 21:27:51 +02:00
evgeny c92d36354a List calling radio and multiview features in README 2026-10-20 21:14:57 +02:00
evgeny a0d49c4bbd Add Vibechat overview and group access notes 2026-10-20 21:14:16 +02:00
evgeny e3dbeee6a8 Document desktop stream tile behavior and verification 2026-10-20 20:47:55 +02:00
evgeny 8673673fcb Handle stream tile coordinates with Qt 5 and Qt 6 APIs 2026-10-20 20:46:08 +02:00
evgeny 03e8caf849 Isolate publisher return test and use native widget input 2026-10-20 20:44:42 +02:00
evgeny 2781208361 Exercise native preview clicks and publisher controls escape 2026-10-20 20:42:23 +02:00
evgeny 64064c2cbf Cover desktop local preview and multiview navigation 2026-10-20 20:39:24 +02:00
evgeny e5510e9f62 Connect desktop multiview to publisher preview and controls 2026-10-20 20:37:13 +02:00
evgeny 44db42180e Notify caller when desktop stream controls close 2026-10-20 20:33:23 +02:00
evgeny 6dab5db56a Show silent local preview and focus remote desktop stream tiles 2026-10-20 20:32:52 +02:00
evgeny f1cccb1c92 Document stream controls navigation and Samsung verification 2026-10-20 20:19:28 +02:00
evgeny b26538c48f Keep replacement camera preview active during tile disposal 2026-10-20 20:15:08 +02:00
evgeny 39bca58515 Open Android stream controls from own multiview tile 2026-10-20 20:11:49 +02:00
evgeny ca7e169811 Keep Android publisher screen focused on capture controls 2026-10-20 20:10:36 +02:00
evgeny fe9c3c74bd Record global stream shortcut verification on Samsung 2026-10-20 20:02:25 +02:00
evgeny d7053a2366 Open active stream controls from any Android header 2026-10-20 19:58:55 +02:00
evgeny 59858a726a Share active stream button across Android group and home headers 2026-10-20 19:56:50 +02:00
evgeny c4da659dcb Keep publisher shortcut available in every desktop group 2026-10-20 19:55:11 +02:00
evgeny 5b6ed6ee78 Exclude own stream from remote stream selectors 2026-10-20 19:52:22 +02:00
evgeny 7e95c3043b Add own live stream shortcut to Android chat header 2026-10-20 19:49:27 +02:00
evgeny 352f5b3f94 Show active publisher shortcut in desktop channel header 2026-10-20 19:46:32 +02:00
evgeny 6c74749dd4 Document direct local multiview preview and Samsung verification 2026-10-20 19:27:38 +02:00
evgeny 5c1619420a Show own Android multiview source through silent camera preview 2026-10-20 19:17:59 +02:00
evgeny c4b2052b27 Label multiview tap targets and record Samsung fullscreen verification 2026-10-20 19:06:14 +02:00
evgeny b46f13920c Expand Android multiview tiles on tap without restarting playback 2026-10-20 19:00:40 +02:00
evgeny d7d018d591 Record Samsung multiview fix verification on live streams 2026-10-20 18:51:32 +02:00
evgeny ba26b14f16 Include decoder frame state in Android stream failure logs 2026-10-20 18:46:57 +02:00
evgeny ea5d1fcd45 Consume repeated viewer demand when delivering its reply 2026-10-20 18:45:49 +02:00
evgeny 68fb937063 Record reproduced multiview lifecycle defects and audio test flake 2026-10-20 17:44:24 +02:00
evgeny 03f7d4341d Document multiview ownership, independent clocks and validation 2026-10-20 17:14:08 +02:00
evgeny b3ebc09b9b Wait for shared Android stream output release before starting calls 2026-10-20 17:13:59 +02:00
evgeny c98fdc6297 Reject duplicate Android catalogue entries before updating grid 2026-10-20 17:12:21 +02:00
evgeny b3116173ca Verify shared stream mixing and avoid retrying terminal closures 2026-10-20 17:12:16 +02:00
evgeny 4a44149c00 Translate Android multiview controls and empty state 2026-10-20 17:07:37 +02:00
evgeny 5f0325e817 Expose watch-all streams from Android chat and preserve catalogue on transient errors 2026-10-20 17:07:31 +02:00
evgeny 9e5b2ad435 Add adaptive Android grid with automatic source reconciliation 2026-10-20 17:07:19 +02:00
evgeny 14b152bb5a Keep Android stream surfaces alive until decoder release and fit grid geometry 2026-10-20 17:07:12 +02:00
evgeny 75806249bd Run Android players concurrently and fall back between decoders 2026-10-20 16:58:41 +02:00
evgeny 4e386fc8e3 Mix Android streams on one AudioTrack with independent clocks 2026-10-20 16:58:32 +02:00
evgeny 57d28376b6 Use independent shared viewers in the Android native bridge 2026-10-20 16:58:25 +02:00
evgeny c8bcf41f4a Translate desktop multiview controls and catalogue states 2026-10-20 16:39:59 +02:00
evgeny fd05ec47ab Connect the all-streams window to chat actions and service lifetime 2026-10-20 16:39:50 +02:00
evgeny bad9ee3a0c Add an automatically updated desktop grid of active streams 2026-10-20 16:39:43 +02:00
evgeny 05deb15c91 Embed stream players and verify grid and concurrent playback 2026-10-20 16:39:34 +02:00
evgeny 1b49c4023b Offer all active streams and share catalogue parsing in the GUI 2026-10-20 16:29:17 +02:00
evgeny 103e0b6865 Keep per-stream playback clocks on the shared audio output 2026-10-20 16:29:06 +02:00
evgeny a0b6dd7ef5 Mix live stream PCM into the shared desktop audio output 2026-10-20 16:27:24 +02:00
evgeny 94697c1af0 Preserve desktop catalogue watches across chat selection 2026-10-20 16:27:17 +02:00
evgeny 4fa9d474ab Track live stream catalogues independently for each owner 2026-10-20 16:27:10 +02:00
evgeny 39446b6e2c Use independent viewer sessions in the desktop stream bridge 2026-10-20 16:13:14 +02:00
evgeny 0bc3b62f46 Add independent live stream viewer sessions in the shared core 2026-10-20 15:53:44 +02:00
evgeny 9c7b49e91f Add call status sharing and automatic stream orientation 2026-10-20 15:49:32 +02:00
evgeny f87cda8b13 Record multicast validation and stabilize report timing test 2026-10-20 15:13:59 +02:00
evgeny b250e8a44d Cover multicast report backpressure, chunking and timer cleanup 2026-10-20 15:08:59 +02:00
evgeny 961c3447d0 Create multicast report channel before checking backpressure 2026-10-20 15:05:16 +02:00
evgeny e59bc9857b Test multicast routing, overload and descriptor lifetime 2026-10-20 15:01:27 +02:00
evgeny 4a1a65c3ba Implement multicast descriptors and receiver subscriptions 2026-10-20 14:53:23 +02:00
evgeny e416d69212 Define descriptor-based multicast API and usage contract 2026-10-20 14:44:23 +02:00
evgeny 8d5459f8fa Connect multicast queues to topology updates and builds 2026-10-20 14:34:55 +02:00
evgeny 5aa28a11d6 Register multicast protocol and core lifecycle 2026-10-20 14:34:30 +02:00
evgeny b02ad6f4cf Add multicast branching queues and bounded loss reports 2026-10-20 14:33:40 +02:00
evgeny de6712de91 Record stream settings validation under an isolated display 2026-10-20 02:30:11 +02:00
evgeny 1e49d2554c Limit desktop and Android stream bitrate menus to 12 Mbit/s 2026-10-20 02:29:46 +02:00
evgeny d2f0828917 Bound restored manual stream bitrate choices to 12 Mbit/s 2026-10-20 02:29:00 +02:00
evgeny 390747343b Document background codec preparation and complete probe validation 2026-10-20 01:28:59 +02:00
evgeny 475bec52ca Distinguish encoder KEY checks from receiver capability probes in tests 2026-10-20 01:27:03 +02:00
evgeny 4db89eeb32 Check cancelled codec preparation cannot publish partial capabilities 2026-10-20 01:25:24 +02:00
evgeny 36e8ab228c Verify startup codec preparation keeps GUI responsive and reuses probes 2026-10-20 01:23:21 +02:00
evgeny 91478e2593 Warm Android video codecs in the background and accelerate probe tails 2026-10-20 01:22:52 +02:00
evgeny e3b74de7ef Prepare and cache desktop video codecs once at application startup 2026-10-20 01:10:44 +02:00
evgeny 0cd1955606 Keep all eight decoder probe frames while accelerating the tail 2026-10-20 01:10:29 +02:00
evgeny 8ad5c09474 Finish decoder capability probes after first paced output and drain 2026-10-20 01:07:31 +02:00
evgeny 7ae204ba4f Document Android startup checks and remaining Linux probe delay 2026-10-20 01:05:53 +02:00
evgeny a4b9367344 Trace first video frame and verify capability upgrades preserve RX 2026-10-20 00:58:37 +02:00
evgeny 74313498f2 Cache verified video codecs and publish receive capabilities early 2026-10-20 00:56:53 +02:00
evgeny d71d0dc4af Check fullscreen video fitting without cropping or rotating thumbnails 2026-10-20 00:54:29 +02:00
evgeny 8b438f26a5 Fit fullscreen call video along the screen without rotating controls 2026-10-20 00:50:05 +02:00
evgeny bea8f1f901 Document Samsung surface ACK deadlock and hardware regression results 2026-10-20 00:43:06 +02:00
evgeny dd5dee2767 Preserve legacy timestamp waits and validate actual surface acknowledgements 2026-10-20 00:42:05 +02:00
evgeny 3eccf58c5e Add hardware TextureView ACK regression probe 2026-10-20 00:39:18 +02:00
evgeny 65f7babb2a Register Android video presentation ACK before the frame draw 2026-10-20 00:38:05 +02:00
evgeny 2c828d481d Record full 60 fps Samsung to Unisoc decode verification 2026-10-20 00:26:11 +02:00
evgeny 49317aab75 Document 60 fps camera modes and presentation recovery 2026-10-20 00:25:33 +02:00
evgeny 3a7aab9186 Cancel Android codec verification when the call stops 2026-10-20 00:24:28 +02:00
evgeny 521dce5528 Use verified Android encoder levels and expose negotiated frame rate 2026-10-20 00:21:21 +02:00
evgeny 3037c5fa87 Verify 50 fps backends and decode all frames during display catch-up 2026-10-20 00:16:23 +02:00
evgeny 52d9a347c3 Bound persistent presentation lag and report catch-up decisions 2026-10-20 00:15:42 +02:00
evgeny 8c826fa2e7 Exercise both video orientations at 30, 50 and 60 fps 2026-10-20 00:15:42 +02:00
evgeny 3db52c755c Preserve phase when sampling 50 fps from a 60 fps camera 2026-10-20 00:15:22 +02:00
evgeny 9bc3e7228c Test Android frame pacing and extend hardware diagnostics to 60 fps 2026-10-20 00:13:48 +02:00
evgeny 0a73d140e6 Account for full refresh-cycle GUI acknowledgement latency 2026-10-20 00:12:26 +02:00
evgeny d8d9f7c4a4 Select camera resolution and frame rate in Android calls 2026-10-20 00:11:15 +02:00
evgeny 27cbf2ba44 Recover persistent video lag by skipping decoded presentation 2026-10-20 00:09:57 +02:00
evgeny 4a759115c9 Probe Android video codecs at 30, 50 and 60 fps 2026-10-20 00:09:56 +02:00
evgeny d991b4c63e Preserve complete generated decoder probe byte arrays 2026-10-20 00:08:16 +02:00
evgeny 238ebcc751 Validate 60 fps probe bitstreams in both orientations 2026-10-20 00:07:53 +02:00
evgeny 0830fe4461 Carry selected video frame rate through desktop call settings 2026-10-20 00:07:36 +02:00
evgeny f6701f81f9 Probe desktop decoders independently at 30 and 60 fps 2026-10-20 00:07:08 +02:00
evgeny 0d08c21330 Select decoder probe rate and preserve HEVC level 4.1 2026-10-20 00:06:45 +02:00
evgeny 4f1af6456d Generate real 60 fps video decoder probe fixtures 2026-10-20 00:06:29 +02:00
evgeny a852a9738b Select camera capture rate and verify 30/60 fps pacing 2026-10-20 00:03:01 +02:00
evgeny ee1e28bff9 Carry selected camera frame rate through isolated capture IPC 2026-10-20 00:02:25 +02:00
evgeny 74a4135cdc Accept faster camera capture modes and pace up to 60 fps 2026-10-20 00:01:13 +02:00
evgeny 9d6dc1b469 Document verified Samsung HEVC High tier support 2026-10-19 23:40:38 +02:00
evgeny c0d5db318f Keep codec mode probes consistent with live encoding 2026-10-19 23:38:53 +02:00
evgeny 7be4b8884c Verify production HEVC modes and cross-platform reception 2026-10-19 23:36:58 +02:00
evgeny 08c74894ef Probe HEVC High tier on Android and desktop receivers 2026-10-19 23:34:15 +02:00
evgeny f2d67990f8 Cover High tier negotiation and independent KEY probes 2026-10-19 23:33:51 +02:00
evgeny 7122d70ea6 Negotiate HEVC Main High tier with explicit level limits 2026-10-19 23:32:29 +02:00
evgeny 5c1807a712 Show actual video call codecs on Android 2026-10-19 23:30:13 +02:00
evgeny 9b5743123b Add standalone Samsung HEVC comparison probe 2026-10-19 23:15:40 +02:00
evgeny 833eeb0a8d Document Full HD call modes and verified codec recovery checks 2026-10-19 22:56:35 +02:00
evgeny 72cb1fa829 Clarify camera mode ownership and codec probe structure 2026-10-19 22:54:55 +02:00
evgeny 7b341d9f4f Cancel desktop decoder probing when a call stops 2026-10-19 22:52:40 +02:00
evgeny c211e17af9 Log Android verified camera modes and guard early camera events 2026-10-19 22:49:57 +02:00
evgeny fcdc098415 Refresh call camera modes on device changes outside the GUI 2026-10-19 22:47:45 +02:00
evgeny 6e0d3f3022 Exercise real Full HD codecs and camera buffer boundaries 2026-10-19 22:46:35 +02:00
evgeny cf2fc67a53 Update camera integration test to nonblocking audio clocks 2026-10-19 22:46:09 +02:00
evgeny 902e7bb921 Use explicit HEVC Main tier and diagnose fixture rejection 2026-10-19 22:45:38 +02:00
evgeny bf8dfeec02 Probe desktop Full HD codecs and retain GPU support by size 2026-10-19 22:37:29 +02:00
evgeny 720ee64fd1 Cover Full HD KEY geometry in native validation tests 2026-10-19 22:37:12 +02:00
evgeny fb660f2b3e Select verified KEY fixtures by actual video geometry 2026-10-19 22:35:56 +02:00
evgeny f50f717b35 Generate landscape and portrait Full HD decoder fixtures 2026-10-19 22:35:34 +02:00
evgeny 7a0bc9516c Populate call resolutions from camera modes and test Full HD IPC 2026-10-19 22:35:05 +02:00
evgeny eb11d2ebc5 Carry native camera modes through Full HD capture protocol 2026-10-19 22:33:59 +02:00
evgeny 9a3ef7b622 Expand Android call previews into available screen space 2026-10-19 22:29:02 +02:00
evgeny 51c6bbb96f Queue Android call camera startup until video probing completes 2026-10-19 21:30:02 +02:00
evgeny c3c88457a8 Document independent video scheduling and verified recovery behavior 2026-10-19 21:22:39 +02:00
evgeny 55e87d20bf Verify generation changes and stale ACK isolation after restart 2026-10-19 21:18:03 +02:00
evgeny 9913222e03 Check video queue publication and nonblocking audio clock parity 2026-10-19 21:16:55 +02:00
evgeny 8c22df8f8e Clarify GUI ownership and preserve video queue payload lifetime 2026-10-19 21:16:10 +02:00
evgeny d0232e4c6e Smooth video presentation phase across render latency changes 2026-10-19 21:15:18 +02:00
evgeny 6f542bfae9 Test video timing with slow decoder and missing presentation ACK 2026-10-19 21:13:21 +02:00
evgeny d9843b8cbd Separate video decoding from event-driven presentation timing 2026-10-19 21:12:02 +02:00
evgeny 93f6fa1d52 Allow video playout diagnostics outside the timer thread 2026-10-19 21:09:22 +02:00
evgeny 402c0c0611 Add bounded video SPSC slots and mutex-free wake events 2026-10-19 21:08:41 +02:00
evgeny 9ca0e61361 Expose nonblocking call clock access through both mutexes 2026-10-19 21:07:44 +02:00
evgeny 562bdf54a6 Add nonblocking jitter clock reads for video scheduling 2026-10-19 21:07:44 +02:00
evgeny 193a549d47 Expose lock-free cumulative call video receive count 2026-10-19 21:07:19 +02:00
evgeny 7b38fd0269 Diagnose decoder work crossing video presentation deadlines 2026-10-19 20:57:45 +02:00
evgeny 10018d008e Update call video controls and sensor rotation across Android and desktop 2026-10-19 20:24:39 +02:00
evgeny ae1d05deda Fix FFmpeg D3D11VA implementation selection on Windows 2026-10-19 19:45:00 +02:00
evgeny 64761fd945 Record verified video builds and intermittent stream audio timing assertion 2026-10-19 19:27:50 +02:00
evgeny 5e38e5b71d Use minimal timer access and diagnose failed video image transforms 2026-10-19 19:24:07 +02:00
evgeny 9d45488369 Require live GPU output before EOS and document presentation-clock buffering 2026-10-19 19:21:48 +02:00
evgeny 16bdf95ba3 Prefer verified Android hardware codecs and use measured low-latency decoder pipeline 2026-10-19 19:21:01 +02:00
evgeny 2a08fd8acd Report decoder stage timings and detect real output stalls independently of playback waits 2026-10-19 19:19:27 +02:00
evgeny ecdba8fb63 Measure presentation cadence and stop latency while preserving unaccepted GPU KEY on fallback 2026-10-19 19:16:17 +02:00
evgeny 243233a20b Test delayed decoder output, four slice threads and complete generation drains 2026-10-19 19:15:05 +02:00
evgeny a4a687be4c Recover real GPU decoder failures on CPU without treating ordinary EAGAIN as frame loss 2026-10-19 19:14:03 +02:00
evgeny f9348ce36f Verify actual bitstreams through asynchronous decoder API and CPU encoder fallback 2026-10-19 19:13:00 +02:00
evgeny 5f45b38cfb Exercise acknowledged frame timing, lossless stalls and queue-dependent deceleration 2026-10-19 19:12:23 +02:00
evgeny 8eb869e41c Enable device-backed FFmpeg hardware decoding and verify exact RX queue accounting 2026-10-19 19:11:07 +02:00
evgeny 4bb2e42a7e Keep decoder reserve based on paced probe rather than transient burst depth 2026-10-19 19:09:17 +02:00
evgeny 895cdd5ac2 Apply presentation-clock queue pacing and three decoded slots to Android 2026-10-19 19:08:51 +02:00
evgeny ecae1cc3c2 Drive desktop video from presentation ACKs with three decoded slots and interruptible deadlines 2026-10-19 19:07:51 +02:00
evgeny 713a972c01 Decode call video through bounded submit/drain with verified GPU and four CPU slice threads 2026-10-19 19:06:52 +02:00
evgeny dc22014bcc Use four CPU encoder workers and retain GPU priority with software fallback 2026-10-19 19:04:08 +02:00
evgeny 28f3b264b8 Anchor video pacing to presentation acknowledgements and total backlog 2026-10-19 19:03:48 +02:00
evgeny baeb4973dd Expose RX frame depth and wake decoding when complete video arrives 2026-10-19 19:02:51 +02:00
evgeny c92f7991ec Record Windows startup GUI stalls and capture-gap scheduling correction 2026-10-19 18:25:34 +02:00
evgeny 40dcc76adb Trace GUI event loop stalls separately from video painting and dispatch 2026-10-19 18:24:57 +02:00
evgeny 47033718ad Apply capture gap recovery cadence consistently on Android 2026-10-19 18:23:25 +02:00
evgeny 526ee5ec8b Test queued capture gaps without dropping frames or delaying ready video 2026-10-19 18:23:25 +02:00
evgeny 9bffe49e62 Bound video display cadence independently of capture timestamp gaps 2026-10-19 18:22:47 +02:00
evgeny 642fc34bcc Bound video recovery correction before media timestamp arithmetic 2026-10-19 17:45:17 +02:00
evgeny 12e9e4da37 Verify GPU backlog drains fully without additional camera inputs 2026-10-19 17:44:14 +02:00
evgeny d266c5da25 Respect GPU pipeline capacity before submitting a new camera frame 2026-10-19 17:43:45 +02:00
evgeny 0f22be6885 Check audio source rate at the actual PCM span boundary 2026-10-19 17:42:49 +02:00
evgeny b7ae7ef700 Document lossless recovery contract and verify actual audio source rate 2026-10-19 17:40:51 +02:00
evgeny a9b91145a6 Document sequential presentation diagnostics and simplify GUI frame ownership 2026-10-19 17:39:54 +02:00
evgeny 4ed2c4bbab Wake video transmission on router queue readiness without polling delay 2026-10-19 17:38:31 +02:00
evgeny 5f1985f9ab Verify RX drain and explicit decoder rejection semantics 2026-10-19 17:37:24 +02:00
evgeny 943f9f2646 Drain receiver backlog before admitting new production and avoid double waiting 2026-10-19 17:35:57 +02:00
evgeny 02e7bbd9af Acknowledge Android frames after RenderThread consumption on all supported APIs 2026-10-19 17:34:44 +02:00
evgeny b11a1beb44 Test lossless mailbox retry after partial video transmission 2026-10-19 17:33:25 +02:00
evgeny 322947777c Stop invalid encoder output explicitly while preserving transient backpressure retries 2026-10-19 17:32:49 +02:00
evgeny c0422a73c0 Drain accepted MediaCodec inputs before bitrate fallback replacement 2026-10-19 17:31:46 +02:00
evgeny 0e53a9f5dd Log retained video batches and verify every GPU input across bitrate changes 2026-10-19 17:31:15 +02:00
evgeny 486d3314ef Acknowledge Android texture consumption before presenting the next frame 2026-10-19 17:30:03 +02:00
evgeny 13f09cfc20 Drain old GPU frames before bitrate replacement and poll outputs while blocked 2026-10-19 17:29:10 +02:00
evgeny 5f772fa97f Drain GPU outputs independently of capture and verify lossless recovery 2026-10-19 17:28:13 +02:00
evgeny 0bc2715a30 Preserve Android encoder outputs and throttle raw input before encoding 2026-10-19 17:25:50 +02:00
evgeny 0a2700a387 Use measured media tempo for sequential Android video playout 2026-10-19 17:25:16 +02:00
evgeny 4e9cce8a01 Present desktop video sequentially through GUI paint acknowledgement 2026-10-19 17:23:58 +02:00
evgeny 0eb743d627 Retain video mailbox tails and pause raw input under backpressure 2026-10-19 17:22:51 +02:00
evgeny 284a1268e4 Preserve encoded chain on temporary video transport backpressure 2026-10-19 17:22:09 +02:00
evgeny 7cbe5375d4 Define audio paced lossless video scheduling interface 2026-10-19 17:21:07 +02:00
evgeny 02a11f7d0a Diagnose Windows call video timing and queue losses 2026-10-19 17:20:12 +02:00
evgeny 21a20da5ee Coordinate Android call audio ownership and improve video controls 2026-10-19 16:51:51 +02:00
evgeny 39ed42da2e Translate call policies and verify desktop phone button colors 2026-10-19 15:20:25 +02:00
evgeny 94e79e5630 Color Android member phone actions using live call presence 2026-10-19 15:20:25 +02:00
evgeny a1f8eaeec2 Show explicit caller choice and already-active radio outcome on Android 2026-10-19 15:20:25 +02:00
evgeny 187fc7fee8 Handle Telecom presentation and pending caller choice notifications 2026-10-19 15:20:25 +02:00
evgeny bd2dd056d6 Honor Telecom incoming UI permission and report phone busy outcomes 2026-10-19 15:20:25 +02:00
evgeny 4cebd0be54 Wire incoming call policy and caller continuation through JNI 2026-10-19 15:20:25 +02:00
evgeny 7d5399cd62 Add five independent Android incoming call preferences 2026-10-19 15:20:25 +02:00
evgeny 97b537c005 Document incoming call policies, busy confirmation and radio status replies 2026-10-19 15:20:04 +02:00
evgeny 558b2a2ac0 Describe ephemeral phone presence in existing BGP flags 2026-10-19 15:19:22 +02:00
evgeny a9d63480cf Document incoming policy and already-active radio contracts 2026-10-19 15:18:49 +02:00
evgeny 27b0f64ec0 Record media regression failures found by full test run 2026-10-19 15:18:09 +02:00
evgeny cda46c0b82 Translate and test already-active radio response with packet loss 2026-10-19 15:05:27 +02:00
evgeny 4deee21d9f Notify caller when subscriber already listens to the channel radio 2026-10-19 15:05:09 +02:00
evgeny 5a318f6f60 Isolate packet loss fixtures between call policy scenarios 2026-10-19 15:03:59 +02:00
evgeny babcb7786a Log phone policy regression state and allow bounded teardown coverage 2026-10-19 15:02:13 +02:00
evgeny b21aeaa6f8 Test normal call busy confirmation and all incoming rejection policies 2026-10-19 14:59:55 +02:00
evgeny 79b4235960 Cover radio phone policy, BGP color flags, retries and caller choice timeout 2026-10-19 14:59:17 +02:00
evgeny 4683c98c08 Apply independent call and radio blocking before phone busy handling 2026-10-19 14:56:58 +02:00
evgeny a72668a491 Represent independent incoming call preferences as one policy mask 2026-10-19 14:56:58 +02:00
evgeny 03a4462407 Reject phone busy calls before any incoming UI when policy is enabled 2026-10-19 14:55:55 +02:00
evgeny a2fdbb6afb Define automatic rejection policy for phone busy subscribers 2026-10-19 14:55:55 +02:00
evgeny d4cd80d3dd Translate phone presence and caller confirmation controls 2026-10-19 14:54:23 +02:00
evgeny 37cf6089e7 Add caller decision controls and colored phone presence on desktop 2026-10-19 14:54:01 +02:00
evgeny b68116eedf Expose phone busy event to desktop call interface 2026-10-19 14:54:01 +02:00
evgeny 6a4a0f45d8 Separate phone status publication from incoming caller warning 2026-10-19 14:51:12 +02:00
evgeny b7aaf268af Wait for caller override before ringing a phone-busy radio subscriber 2026-10-19 14:48:39 +02:00
evgeny be367a08b6 Gate incoming calls on explicit caller decision when phone is busy 2026-10-19 14:47:59 +02:00
evgeny 6ad9c8c80b Define pending decision state for telephone busy warning 2026-10-19 14:46:47 +02:00
evgeny 7ed1a9b167 Carry phone presence in existing BGP and member flag bytes 2026-10-19 14:46:47 +02:00
evgeny 505185430c Define live phone presence and call continuation API 2026-10-19 14:46:16 +02:00
evgeny 1d28ced4f4 Replace Android member radio badge with a green radio call button 2026-10-19 14:30:35 +02:00
evgeny fdd39e82e2 Show desktop radio subscription on the call icon and allow Android icon tint 2026-10-19 14:30:35 +02:00
evgeny aca14bfb70 Select the radio ringtone in both Android ringtone playback paths 2026-10-19 14:25:27 +02:00
evgeny 7693db7b4d Expose radio ringtone enable and volume settings on desktop 2026-10-19 14:25:12 +02:00
evgeny 30f79f7a8d Play the dedicated desktop ringtone for incoming radio calls 2026-10-19 14:25:11 +02:00
evgeny cf4edbbf62 Add a distinct three-tone radio call ringtone for desktop and Android 2026-10-19 14:25:11 +02:00
evgeny 9712a0a583 Check desktop call buttons, online changes, drags, and shifted radio mute control 2026-10-19 14:22:46 +02:00
evgeny cd58903101 Connect member row call actions and retain invitations in the context menu 2026-10-19 14:21:52 +02:00
evgeny a8c2ce8401 Render and handle speaker, radio call, and phone buttons in desktop member rows 2026-10-19 14:21:37 +02:00
evgeny dad819282a Expose live member availability to desktop action buttons 2026-10-19 14:21:37 +02:00
evgeny 04acb6f836 Check radio timer ownership through public service lifecycle 2026-10-19 14:14:52 +02:00
evgeny c0626e0387 Verify idle radio calls have no timers and reject invalid invitation expiry 2026-10-19 14:13:45 +02:00
evgeny e61dc8cd06 Wait for Android channel loading once before radio activation 2026-10-19 14:11:49 +02:00
evgeny a0e440c0f5 Use readable radio call states and completion reasons in logs 2026-10-19 14:11:49 +02:00
evgeny 1b3269f76b Require active subscription on radio acceptance and verify live BGP gating 2026-10-19 14:10:35 +02:00
evgeny 613a75becc Schedule only active radio deadlines and reject late terminal answers 2026-10-19 14:09:10 +02:00
evgeny 5f9e9975d3 Initialize radio router channels before checking send backpressure 2026-10-19 14:07:39 +02:00
evgeny a73d829080 Exercise radio invitations over routed network with deadlines and packet loss 2026-10-19 14:05:29 +02:00
evgeny a831cf6295 Translate desktop radio invitation windows and outcomes 2026-10-19 14:04:45 +02:00
evgeny b57c8e5041 Move Android message action to member details and translate radio call UI 2026-10-19 14:03:24 +02:00
evgeny 25376197db Open channel radio from Android calls and move invitation into user details 2026-10-19 14:02:56 +02:00
evgeny 62a976aef5 Add Android radio call controls and incoming overlay 2026-10-19 14:01:52 +02:00
evgeny 9bd9f04bcf Dispatch Android radio call events and clear them before core restart 2026-10-19 14:01:28 +02:00
evgeny 949c300c53 Set radio invitation timeout to one minute 2026-10-19 14:01:27 +02:00
evgeny 23ece16940 Own pending Android radio calls independently of Activity and ViewModel 2026-10-19 14:00:44 +02:00
evgeny dbb07df7e9 Support incoming radio ringtone and notification actions on Android 2026-10-19 14:00:43 +02:00
evgeny b48a91853d Confirm Android radio activation and support explicit channel selection 2026-10-19 13:59:35 +02:00
evgeny 34890ea709 Bridge Android radio invitation commands to the core thread 2026-10-19 13:59:34 +02:00
evgeny a97c915663 Fix radio signaling and desktop channel type references 2026-10-19 13:58:39 +02:00
evgeny 3f97dafbf7 Show desktop radio calls and activate channel radio after acceptance 2026-10-19 13:58:06 +02:00
evgeny 427794fed8 Expose explicit desktop radio activation for accepted invitations 2026-10-19 13:57:30 +02:00
evgeny 858ba38caf Add radio call action to desktop channel members 2026-10-19 13:57:29 +02:00
evgeny 310d997af3 Deliver radio invitation events to desktop UI 2026-10-19 13:57:29 +02:00
evgeny 849f1c8618 Start and stop radio invitation service with chat lifecycle 2026-10-19 13:56:35 +02:00
evgeny b0fe2d66af Coordinate busy state between telephone and radio invitations 2026-10-19 13:56:35 +02:00
evgeny 7f4ac2fadf Register radio invitation service and shared core events 2026-10-19 13:56:17 +02:00
evgeny 639be7fcc2 Add channel radio invitation signaling and bounded result cache 2026-10-19 13:56:06 +02:00
evgeny a84b226b18 chatgui: enlarge member availability indicator and remove white outline 2026-10-19 13:23:40 +02:00
evgeny 214498f892 Open broadcast controls when selecting the local stream 2026-10-19 12:54:43 +02:00
evgeny 62633bc924 Show the group stream icon only for active broadcasts
Open a single active stream directly and show a selection for multiple streams. Move stream publishing and management into the group menu.
2026-10-19 12:51:56 +02:00
evgeny ffe563bb9f Enable VibeChat UTUN service and package the Wintun driver
Add a settings button to open the current config in an external editor. Wait for core, UTUN and chat startup before reporting readiness; verify startup failures and restarts. Include Wintun DLL and license notices in Windows builds and installers.
2026-10-19 12:33:35 +02:00
evgeny bdb6bf80a4 Free Android stream preview space with start and stop icons 2026-10-19 12:18:42 +02:00
evgeny d0bbe8444e Refine Android stream icons and show channel in title 2026-10-19 12:08:57 +02:00
evgeny 1084cd10ec Compact Android stream controls into one icon toolbar 2026-10-19 11:51:33 +02:00
evgeny ec545a8665 Remove the minimized-to-tray notification 2026-10-19 10:44:29 +02:00
evgeny d7f30d7bb1 Activate the existing VibeChat window on repeated launches 2026-10-19 10:29:12 +02:00
evgeny 50017b7f74 Sync configured chat names and embed the Windows application icon 2026-10-19 09:54:42 +02:00
evgeny 7140775d8d Preserve source context when applying the live QP dependency patch 2026-10-18 22:30:28 +02:00
evgeny 5568331510 Keep the QP adaptation tooltip readable in source 2026-10-18 22:26:23 +02:00
evgeny 242d0f5493 Verify the QP ceiling constrains real HEVC output under bitrate pressure 2026-10-18 22:24:55 +02:00
evgeny 6e0b842858 Test live QP driver updates and rejection handling against patched FFmpeg 2026-10-18 22:23:23 +02:00
evgeny 2aa890201d Package live AMF QP support with the FFmpeg build profile 2026-10-18 22:20:44 +02:00
evgeny aff8a21ae4 Stop raising QP as soon as measured bitrate returns to target 2026-10-18 22:11:48 +02:00
evgeny fae794d39e Persist broadcast QP controls and verify smooth rate feedback 2026-10-18 22:11:29 +02:00
evgeny fe86a16cac Support live AMF QP ceiling updates in bundled FFmpeg 2026-10-18 22:08:47 +02:00
evgeny 00698537ad Add QP ceiling and adaptation controls to the broadcast window 2026-10-18 22:07:36 +02:00
evgeny df02aa8170 Adapt the stream QP ceiling from measured encoded bitrate 2026-10-18 22:06:34 +02:00
evgeny 0070221045 Apply configured QP ceilings and expose live encoder adjustment capability 2026-10-18 22:05:53 +02:00
evgeny 54b50f4177 Define stream QP ceiling and smooth bitrate feedback controller 2026-10-18 22:05:33 +02:00
evgeny a51af91718 Use AMF remote desktop latency mode for HEVC broadcasts 2026-10-18 21:51:54 +02:00
evgeny bd92ac0c88 Ensure the minimal Windows FFmpeg build includes HEVC header parsing 2026-10-18 19:52:41 +02:00
evgeny 4b88402f84 Verify FFmpeg diagnostic callback restoration 2026-10-18 19:49:04 +02:00
evgeny 0cfc29d9eb Restore FFmpeg diagnostics after Qt multimedia initializes its logger 2026-10-18 19:48:34 +02:00
evgeny d1ba26f8ac Log converted encoder input detail alongside HEVC quantization 2026-10-18 19:46:35 +02:00
evgeny 6d5a626b9b Include HEVC header tracing in bundled FFmpeg and round-trip tests 2026-10-18 19:45:36 +02:00
evgeny f7853f145c Trace HEVC key frame quantization and reduce AMF log noise 2026-10-18 19:44:38 +02:00
evgeny 78b147f806 Expose AMF driver diagnostics and effective encoder settings 2026-10-18 18:50:20 +02:00
evgeny b8bc9b409a Fix Android stream layout and show measured publisher bitrate 2026-10-18 18:24:30 +02:00
evgeny e246357f92 Document valid HEVC PPS support and shared startup verification 2026-10-18 17:33:13 +02:00
evgeny aedb0e6170 Cover HEVC PPS flags and incompatible AMF startup output 2026-10-18 17:21:05 +02:00
evgeny f8827a9466 Accept valid HEVC PPS flags and verify call GPU probes fully 2026-10-18 17:19:57 +02:00
evgeny 0730fb6bdd Описать GPU-путь звонка, границы буферизации и проверку задержки 2026-10-18 17:10:17 +02:00
evgeny 5e672f01d9 Проверить отмену пачки видеокадров при завершении звонка 2026-10-18 17:05:54 +02:00
evgeny 66526ad4a5 Проверить готовую пачку GPU через транспорт и обновить JNI видеопорта 2026-10-18 17:05:00 +02:00
evgeny 86a278ee99 Передавать готовую пачку GPU атомарно через TX mailbox 2026-10-18 17:01:22 +02:00
evgeny 0343825746 Показывать фактическую глубину GPU-конвейера без дополнительной TX-очереди 2026-10-18 16:57:49 +02:00
evgeny 09f48403c5 Проверить GPU-конвейер на задержке, пакетной выдаче и отказе замены 2026-10-18 16:55:31 +02:00
evgeny 2facdb6949 Сохранять выдачу старого GPU до первого IDR замены 2026-10-18 16:54:36 +02:00
evgeny ae8eeab490 Выдавать готовые кадры GPU без дополнительного ожидания в TX 2026-10-18 16:51:55 +02:00
evgeny 6715acdef8 Добавить GPU-конвейер звонка с исходными PTS и подтверждением смены по IDR 2026-10-18 16:50:33 +02:00
evgeny 3ed9acb384 Устранить сжатие панели звонка и распараллелить HEVC внутри кадра 2026-10-18 16:28:36 +02:00
evgeny 21e4821e22 Ограничить камеру звонка до 30 fps перед конвертацией 2026-10-18 16:27:43 +02:00
evgeny f6051d3bcd Показывать этапы первого долгого кадра в интервале 2026-10-18 16:18:42 +02:00
evgeny 5a55bcb500 Диагностика задержек программного видео на desktop 2026-10-18 16:17:51 +02:00
evgeny 03ff431d78 Avoid Windows interface macro collision in local transport 2026-10-18 15:29:34 +02:00
evgeny 4c62f45984 Bound local discovery traffic and validate invitations 2026-10-18 15:18:40 +02:00
evgeny 80b23997c0 Use stream category filters in desktop stream tests 2026-10-18 15:10:59 +02:00
evgeny f6f8647091 Decouple file network test from temporary packet logs 2026-10-18 15:10:57 +02:00
evgeny 0e2253cdc8 Remove Android video timing probes and categorize radio logs 2026-10-18 15:10:06 +02:00
evgeny 044a20d4a0 Clean desktop stream lifecycle and event bridge logging 2026-10-18 15:09:24 +02:00
evgeny b40ba9308f Route desktop call and PTT diagnostics to their categories 2026-10-18 15:08:57 +02:00
evgeny 74e2238b7f Categorize file transfer and browser logs and reduce I/O noise 2026-10-18 15:08:42 +02:00
evgeny 81ee235f73 Keep file request diagnostics in media and drop packet noise 2026-10-18 15:07:45 +02:00
evgeny dcdc700d8d Remove temporary per-packet file routing diagnostics 2026-10-18 15:06:54 +02:00
evgeny 81de8747e2 Move video call and stream diagnostics to module categories 2026-10-18 15:06:16 +02:00
evgeny 28826e050c Add local UDP discovery and invitation delivery for chat clients 2026-10-18 14:46:04 +02:00
evgeny aad295c9d0 Render encrypted group attachments correctly on Android 2026-10-18 13:14:56 +02:00
evgeny b3495349e1 Offer attachment encryption after selecting a file 2026-10-18 11:47:53 +02:00
evgeny 7e08135bba Remove unpublished cipher block indexes during recovery 2026-10-18 10:47:24 +02:00
evgeny 057bdb3112 Recover cancelled unpublished encryption jobs without retaining keys 2026-10-18 10:46:56 +02:00
evgeny a31ade1054 Exercise group encryption choice through real Qt input events 2026-10-18 10:44:23 +02:00
evgeny 98f71735a0 Document encrypted group attachment format and grant lifecycle 2026-10-18 10:42:16 +02:00
evgeny 1896a19eba Explain exact encrypted container rejection reasons 2026-10-18 10:41:27 +02:00
evgeny 8a46a53a21 Verify cache restoration and channel cleanup for encrypted attachments 2026-10-18 10:40:24 +02:00
evgeny 5d2522b8de Account decrypted copies in media quota and protect active containers 2026-10-18 10:39:29 +02:00
evgeny feb327afc7 Preserve durable publication and restore evicted decrypted files 2026-10-18 10:39:03 +02:00
evgeny 3c395dfe5d Share durable encrypted file publication with direct messages 2026-10-18 10:39:03 +02:00
evgeny 4844253f12 Size storage-role query for complete signed-role predicate 2026-10-18 10:37:19 +02:00
evgeny 01e1772615 Use signed storage role and reject revoked key recipients 2026-10-18 10:37:12 +02:00
evgeny fd61aedce3 Use signed storage role in attachment replication fixture 2026-10-18 02:31:55 +02:00
evgeny 9f36fb0ddd Release fixture history gate after verified member synchronization 2026-10-18 02:26:30 +02:00
evgeny de1da1c9b1 Translate encrypted attachment controls and request states 2026-10-18 02:26:01 +02:00
evgeny 3f48a145ae Trace group history readiness in attachment network test 2026-10-18 02:25:35 +02:00
evgeny 6c8e2763e5 Expose manual download API and distinguish storage replication in test 2026-10-18 02:19:45 +02:00
evgeny 945208ce77 Register encrypted attachment unit and network tests 2026-10-18 02:19:11 +02:00
evgeny 62a4f60508 Test encrypted containers and consent delivery across restart 2026-10-18 02:19:10 +02:00
evgeny ada1406d79 Keep membership signature regressions on shared verifier 2026-10-18 02:18:21 +02:00
evgeny ade9401e05 Fix desktop attachment UI include path 2026-10-18 02:17:54 +02:00
evgeny ad7050ad2c Fix shared cipher linkage and transport type includes 2026-10-18 02:17:18 +02:00
evgeny 7cffb15c73 Add author request list with individual key approvals 2026-10-18 02:17:08 +02:00
evgeny 2b7def369d Render locked group attachments and local decrypted media 2026-10-18 02:16:29 +02:00
evgeny 9f813424bb Deliver attachment key state changes to desktop UI 2026-10-18 02:15:25 +02:00
evgeny 4703a46eb9 Add per-send encryption toggle for group files and voice 2026-10-18 02:15:16 +02:00
evgeny 61d1561612 Bind encrypted manifests and request keys after verified download 2026-10-18 02:14:31 +02:00
evgeny 41696b7e0b Route encrypted group preparation through key owner 2026-10-18 02:14:26 +02:00
evgeny e5a1fc5a48 Start and stop attachment key owner with chat service 2026-10-18 02:13:54 +02:00
evgeny 60e040677b Declare attachment grant service and lifecycle state 2026-10-18 02:13:40 +02:00
evgeny 321ed8e747 Implement durable encrypted attachment grants and requests 2026-10-18 02:13:28 +02:00
evgeny e45401449e Share complete membership verification for private grants 2026-10-18 02:10:11 +02:00
evgeny 6a90d79d04 Add authenticated encrypted attachment container 2026-10-18 02:09:30 +02:00
evgeny b4ef4ec919 Switch message cipher consumers to shared media API 2026-10-18 02:08:52 +02:00
evgeny 9c22b04cb0 Use common file cipher primitives in direct messages 2026-10-18 02:08:45 +02:00
evgeny d6db3d18ce Extract shared CCM and streaming media cryptography 2026-10-18 02:08:29 +02:00
evgeny be295f768c feat(chat): add local DM deletion and improve Android member list
Delete local conversations atomically, retain replay protection and sequence counters, and guard asynchronous media work by history generation. Add Android avatar menu and confirmation, persistent file cleanup, and regression coverage.

Fix unnamed member wire padding and compact Android member action spacing.

Validation: 158 core tests passed; targeted DM tests, desktop build, Android unit tests and debug APK build passed.
2026-10-18 02:04:05 +02:00
evgeny 97710b609f test(nat): require OPEN for public TCP listeners receiving connections 2026-10-18 01:02:08 +02:00
evgeny 75d383f89d docs(nat): describe passive incoming connection evidence 2026-10-18 00:59:11 +02:00
evgeny a20a219063 fix(core): free pending ping payloads when destroying instance 2026-10-18 00:57:11 +02:00
evgeny 6075b4cd0f test(nat): verify public incoming profiles on isolated routed network 2026-10-18 00:55:37 +02:00
evgeny 49385ab91c test(nat): isolate active measurements from incoming transport evidence 2026-10-18 00:54:51 +02:00
evgeny 094a8bb499 test(nat): cover accepted UDP and TCP profiles and LAN exclusions 2026-10-18 00:42:35 +02:00
evgeny df2f6ff300 feat(nat): confirm direct open profile from accepted public connections 2026-10-18 00:41:53 +02:00
evgeny 37e092672a fix(nat): retain cold ingress reservation after partial measurements 2026-10-17 23:53:09 +02:00
evgeny 7bf877b7d6 test(nat): exercise full retry budget with high RTT and lost reports 2026-10-17 23:45:35 +02:00
evgeny 305b61ccab fix(nat): advance after an unfinished pair uses its full retry budget 2026-10-17 23:43:21 +02:00
evgeny 1d1f5d081f test(nat): reserve fresh helper before publishing it during recheck 2026-10-17 23:41:51 +02:00
evgeny edc78cbf4a test(nat): cover helper rotation, preserved OPEN and budget resume 2026-10-17 23:39:17 +02:00
evgeny a72e514dc5 fix(nat): keep fresh ingress checks active during profile rechecks 2026-10-17 23:38:52 +02:00
evgeny 6ad3674904 fix(nat): continue helper traversal after partial mapping results 2026-10-17 23:37:10 +02:00
evgeny 7c7b9646f3 test(android): distinguish untranslated and unmeasured interface addresses 2026-10-17 23:20:55 +02:00
evgeny 575a7bfe32 fix(android): show no NAT and inbound status instead of interface 2026-10-17 23:20:55 +02:00
evgeny cb8e654639 fix(android): preserve measured profiles in member address details 2026-10-17 23:20:55 +02:00
evgeny 3f7cfe1c86 fix(chatgui): distinguish untranslated addresses from unmeasured profiles 2026-10-17 23:19:25 +02:00
evgeny a485b10e63 fix(chatgui): show measured NAT profile in member addresses 2026-10-17 23:18:57 +02:00
evgeny 3e29a7ca1c test(android): expect distinct NAT? and EIM? address labels 2026-10-17 22:17:53 +02:00
evgeny 6cbcb860d6 fix(android): distinguish unmeasured NAT from NAT with unknown type 2026-10-17 22:07:59 +02:00
evgeny 86c08092af feat(android): show NAT profile and external address for own sockets 2026-10-17 22:07:58 +02:00
evgeny 1dfe349eb8 fix(android): consume local socket snapshots on core events 2026-10-17 22:07:58 +02:00
evgeny c69f8d8975 fix(nat): notify GUI and include profiles in Android socket snapshots 2026-10-17 22:07:58 +02:00
evgeny 60104ea093 fix(chatgui): label detected NAT with unknown type as NAT? 2026-10-17 22:02:36 +02:00
evgeny 2513e9ae81 tests: finish cold UDP detection before opening additional TCP links 2026-10-17 21:22:22 +02:00
evgeny d2a8e6fda7 db: accept TCP IP-only addresses while preserving stored projections 2026-10-17 19:58:54 +02:00
evgeny 2c7c3c9e8b tests: allow TCP IP observations from existing incoming links 2026-10-17 19:54:18 +02:00
evgeny 857092508a docs: explain TCP NAT presence and IP-only addresses 2026-10-17 19:53:34 +02:00
evgeny b588f8e9f4 tests: verify TCP IP-only detection across real NAT gateways 2026-10-17 19:52:39 +02:00
evgeny 62aee9f01c tests: cover TCP NAT presence and zero-port address publication 2026-10-17 19:50:33 +02:00
evgeny c42d75c2f5 nat: limit helper selection and topology retries to UDP 2026-10-17 19:49:42 +02:00
evgeny 5c0db6ce9e nat: remove TCP listener probes from endpoint detection 2026-10-17 19:47:37 +02:00
evgeny 6363c8b7ea nat: publish TCP external IPs with an unknown port 2026-10-17 19:46:33 +02:00
evgeny 5eb3526186 etcp: exchange observed IPs on established TCP links 2026-10-17 19:46:02 +02:00
evgeny 95f209d098 nat: determine TCP translation from one public IP observation 2026-10-17 19:45:29 +02:00
evgeny d7ad58b380 docs: clarify STUN result fields and API usage 2026-10-17 18:50:39 +02:00
evgeny dbe2640e74 nat: reject local STUN paths as Internet mapping evidence 2026-10-17 18:50:10 +02:00
evgeny 7a40ba536e tests: verify STUN estimates and ETCP promotion in isolated networks 2026-10-17 18:48:06 +02:00
evgeny 8983026625 docs: describe same-interface STUN estimates and working endpoint addresses 2026-10-17 18:47:41 +02:00
evgeny f5d923a671 tests: cover tentative STUN mapping, expiry and native priority 2026-10-17 18:46:38 +02:00
evgeny 417b848b50 nat: publish observed working addresses with tentative STUN profiles 2026-10-17 18:45:20 +02:00
evgeny 88ac08333e nat: use same-interface STUN mapping as tentative EIM 2026-10-17 18:45:02 +02:00
evgeny aede36388f docs: define EIM? as matching mapping with unknown inbound access 2026-10-17 18:27:16 +02:00
evgeny 906f247588 tests: verify tentative EIM with known helper and unknown inbound access 2026-10-17 18:25:53 +02:00
evgeny fad9fbe6c3 android: label unverified EIM and observed unknown NAT addresses 2026-10-17 18:19:47 +02:00
evgeny b539a6f338 gui: display EIM? when unsolicited ingress remains unverified 2026-10-17 18:19:23 +02:00
evgeny 58755dd75e nat: distinguish EIM with unverified unsolicited ingress 2026-10-17 18:19:23 +02:00
evgeny bbb8cff4a6 nat: prefer fresh public helpers while retaining known mapping candidates 2026-10-17 18:10:23 +02:00
evgeny 3c321ac59c docs: explain observed NAT candidates in signed node snapshots 2026-10-17 18:05:30 +02:00
evgeny eb09a675c7 nat: preserve the NAT address kind when mapping is unknown 2026-10-17 18:01:09 +02:00
evgeny 4284233e6f nat: keep unchanged public addresses distinct from unknown NAT 2026-10-17 17:59:22 +02:00
evgeny 5a8b05c50f nat: try known mapping peers before observer-only fallback 2026-10-17 17:57:15 +02:00
evgeny b9a5981f5c gui: shorten unknown NAT status to NAT? 2026-10-17 17:55:32 +02:00
evgeny 78f71ddbb0 nat: distinguish public interface addresses from unknown NAT candidates 2026-10-17 17:53:20 +02:00
evgeny 37461bb938 nat: finish observer-only rounds and document unknown-type candidates 2026-10-17 17:50:28 +02:00
evgeny 71abf74bfc tests: cover unknown NAT candidates and stalled ingress control 2026-10-17 17:48:55 +02:00
evgeny 79d8789410 nat: prioritize mapping candidates and label unknown NAT explicitly 2026-10-17 17:47:18 +02:00
evgeny 6037819269 nat: retain observed candidates and continue mapping after ingress failures 2026-10-17 17:45:24 +02:00
evgeny b96ae1a718 docs: introduce NAT detector results and basic usage 2026-10-17 17:18:07 +02:00
evgeny 6a2164717e docs: describe NAT detector state and public API arguments 2026-10-17 17:12:40 +02:00
evgeny eb3dd7f237 docs: explain NAT detection through its main idea and steps 2026-10-17 17:06:04 +02:00
evgeny d70d6cb66a tests: ignore stale helper probes and document local source rejection 2026-10-17 16:56:21 +02:00
evgeny 83efa229ed nat: reject local probe sources and preserve internet profiles on LAN 2026-10-17 16:54:07 +02:00
evgeny 308eb07742 docs: align endpoint and STUN contracts with the implemented detector 2026-10-17 16:32:08 +02:00
evgeny d5715a1f4f tests: wait for the requested NAT round instead of an earlier automatic result 2026-10-17 16:26:35 +02:00
evgeny 27a87412c5 tests: verify STUN diagnostics without publishing a foreign-port profile 2026-10-17 16:23:18 +02:00
evgeny 7673316dc8 docs: specify NAT v4 independent mapping reports and receiver-verified ingress 2026-10-17 16:19:47 +02:00
evgeny 4fab849917 nat: align probe timing and test receiver IP rejection and endpoint failover 2026-10-17 16:06:21 +02:00
evgeny 38447da5e8 nat: retry partial ingress measurements and keep known-IP anchor replies available 2026-10-17 16:02:01 +02:00
evgeny 8158d6a435 tests: exercise NAT mapping, filtering, delayed ingress and contaminated history 2026-10-17 15:57:49 +02:00
evgeny 3cb971fcba tests: wait for READY group routes before measuring NAT 2026-10-17 15:56:19 +02:00
evgeny 110dd82932 tests: separate STUN diagnostics and allow complete NAT probe rounds 2026-10-17 15:51:32 +02:00
evgeny 26ab3b13b4 nat: separate routed mapping reports from unsolicited UDP ingress 2026-10-17 15:43:38 +02:00
evgeny df80c5745d transport: support one-way authenticated NAT probes 2026-10-17 15:24:57 +02:00
evgeny 1dc26bf715 Add bounded mouse zoom and panning to live stream viewer 2026-10-17 01:49:35 +02:00
evgeny 93dc21f3c8 Exercise capture conversion failure with distinct source generations 2026-10-17 01:30:48 +02:00
evgeny fd73fae77f Keep stream capture failures and cursor snapshots tied to their source 2026-10-17 01:30:06 +02:00
evgeny 9c7d088f8b Compare retained image pixels without assuming SIMD color rounding 2026-10-17 01:30:05 +02:00
evgeny 64bbbdc631 Guard RGB conversion bounds and use padded frames in file playback 2026-10-17 01:28:42 +02:00
evgeny f81b93ad0d Allocate padded RGB frames for FFmpeg video conversion 2026-10-17 01:28:04 +02:00
evgeny 88e3e27145 Show cursor in Windows stream preview 2026-10-17 01:02:46 +02:00
evgeny bf729502a1 Improve Windows screen capture frame rate 2026-10-17 00:38:29 +02:00
evgeny f5660a4642 Hide window capture sources 2026-10-17 00:19:28 +02:00
evgeny e440c62339 Use native Windows monitor handle for cursor overlay 2026-10-17 00:16:56 +02:00
evgeny 4a6f95cebd Add native Windows cursor overlay to screen broadcasts 2026-10-16 23:50:52 +02:00
evgeny 49d55a25a1 Poll stream image thread cleanup from GUI loop 2026-10-16 23:09:29 +02:00
evgeny 1e21912dc6 Trace stream image worker and GUI shutdown waits 2026-10-16 22:45:58 +02:00
evgeny a63af43e59 Handle AMF periodic keyframes 2026-10-16 21:52:10 +02:00
evgeny 98d0040b27 Fix AMF live encoder startup probe 2026-10-16 21:26:58 +02:00
evgeny 2a439754ba Fix Windows FFmpeg configure link flags 2026-10-16 19:42:47 +02:00
evgeny 4401c4b1e4 Fix libaom build with NASM 3 2026-10-16 19:27:51 +02:00
evgeny 8cb656dbdc Minimize FFmpeg features for ChatGUI 2026-10-16 19:08:53 +02:00
evgeny eb98d2c724 Fetch x265 tags before configuring version metadata 2026-10-16 19:04:25 +02:00
evgeny f90cbae94a Enable AMD AMF in Windows ChatGUI FFmpeg build 2026-10-16 18:50:42 +02:00
evgeny 5116496565 Record thread exit evidence from latest Windows stream log 2026-10-16 18:09:51 +02:00
evgeny 7a2fa9e199 Move captured frame conversion to persistent worker 2026-10-16 18:08:42 +02:00
evgeny 5c9bf9e47c Log capture conversion thread and completion 2026-10-16 18:05:58 +02:00
evgeny 8d7ab6a1a6 Keep a converted frame for encoder reconfiguration 2026-10-16 18:05:07 +02:00
evgeny 97e20d2f1c Keep Qt video frame conversion off the publisher worker 2026-10-16 18:04:27 +02:00
evgeny c27ee36cfb Record passing publisher lifecycle regression suite 2026-10-16 17:39:12 +02:00
evgeny 37eccd06ea Record adaptive audio validation and confirmed stream startup failure 2026-10-16 17:38:32 +02:00
evgeny 16e547d15d Drain publisher while asynchronous microphone teardown completes 2026-10-16 17:34:21 +02:00
evgeny 114c0b3e2f Aggregate recurring audio glitch logs between buffer changes 2026-10-16 17:33:32 +02:00
evgeny 688d559787 Wait for native thread exit outside GUI and cover FIN drain in tests 2026-10-16 17:31:20 +02:00
evgeny 0f5a5580c5 Test publisher shutdown with GUI-dependent thread-local cleanup 2026-10-16 17:27:15 +02:00
evgeny 85101765eb Keep GUI responsive until publisher threads finish resource cleanup 2026-10-16 17:26:30 +02:00
evgeny fb2a615165 Reproduce Android audio startup deadlock with real Opus playback 2026-10-16 17:25:19 +02:00
evgeny c03fe3da71 Prime late stream audio without waiting for its playback clock 2026-10-16 17:24:25 +02:00
evgeny 0c26daf3f5 Document adaptive buffer limits and preserve failed-open backoff 2026-10-16 17:18:13 +02:00
evgeny b463fc3309 Keep adaptive requests above baseline and test backend fault events 2026-10-16 17:17:22 +02:00
evgeny e37b3be7da Defer new shared subscribers during microphone buffer resizing 2026-10-16 17:15:51 +02:00
evgeny ca09073a52 Test gradual audio buffer adaptation and nonblocking microphone stop 2026-10-16 17:13:59 +02:00
evgeny efe9e8311c Detach shared capture safely while its audio buffer is resizing 2026-10-16 17:12:51 +02:00
evgeny 3c73c7d645 Keep microphone buffer resizing outside the GUI close path 2026-10-16 17:11:57 +02:00
evgeny 0b58bf3c87 Increase audio buffer gradually after repeated backend glitches 2026-10-16 17:10:31 +02:00
evgeny 360d5dddaa Expose WASAPI and Linux audio buffer glitches to device owners 2026-10-16 17:08:55 +02:00
evgeny 38eae06161 Document microphone watchdogs and pending stream diagnostics 2026-10-16 17:04:46 +02:00
evgeny c37be1c3e8 Trace stream audio startup demand and link Windows COM cleanup 2026-10-16 16:58:01 +02:00
evgeny 014a110fd5 Verify stopping during asynchronous microphone cleanup 2026-10-16 16:53:10 +02:00
evgeny 69cee1bec4 Check continuing H265 screen video and avoid waiting on failed input 2026-10-16 16:51:43 +02:00
evgeny 2de9ac85a2 Test missing microphone PCM in calls and radio without GUI stalls 2026-10-16 16:50:44 +02:00
evgeny cb84d1049f Translate call and radio microphone timeout messages 2026-10-16 16:49:47 +02:00
evgeny 91357ebf90 Show microphone timeout errors in call and radio controls 2026-10-16 16:49:09 +02:00
evgeny 110af9b0c5 Keep normal capture lifecycle synchronous after healthy input 2026-10-16 16:49:09 +02:00
evgeny 432f2dcf00 Stop radio transmission when microphone PCM stops arriving 2026-10-16 16:48:34 +02:00
evgeny 26f6e2ee83 Disable stalled call microphones and close capture asynchronously 2026-10-16 16:48:10 +02:00
evgeny 48cb101047 Expose microphone PCM timeout to shared capture consumers 2026-10-16 16:48:10 +02:00
evgeny 05f1fe485c Trace stream video progress and detect missing microphone PCM 2026-10-16 16:47:25 +02:00
evgeny 349869f732 Record stream startup validation and Windows follow-up 2026-10-16 16:21:11 +02:00
evgeny 230687d155 Wait for asynchronous microphone release in stream tests 2026-10-16 16:19:02 +02:00
evgeny de71617e9f Initialize COM for capture cleanup and release completed leases 2026-10-16 16:19:02 +02:00
evgeny 543c9decba Exclude retiring capture sessions from new subscriptions 2026-10-16 16:15:20 +02:00
evgeny 9629e9311c Defer CPU rejection until dialog destruction completes 2026-10-16 16:15:07 +02:00
evgeny 21f4de492c Test stream startup consent and nonblocking microphone failure 2026-10-16 16:13:35 +02:00
evgeny 7a660688af Translate stream startup failures and CPU confirmation 2026-10-16 16:12:37 +02:00
evgeny 9500581e0b Gate stream encoding on microphone input and CPU consent 2026-10-16 16:11:04 +02:00
evgeny 3ba7601ba4 Close failed stream capture without blocking the GUI 2026-10-16 16:03:14 +02:00
evgeny 86da11b2e1 Separate hardware and software live encoder selection 2026-10-16 15:58:25 +02:00
evgeny 903568d9d6 Apply the selected language immediately in first-run setup 2026-10-16 15:34:31 +02:00
evgeny debfccd7fa Add language selection to the ChatGUI first-run setup 2026-10-16 15:34:20 +02:00
evgeny 91620cec4e Add nickname setup on the first ChatGUI launch 2026-10-16 15:32:33 +02:00
evgeny 5074bad57c Fix Android avatar viewer bounds around system bars 2026-10-16 15:17:12 +02:00
evgeny 0475df8412 Close Android stream viewer after playback ends 2026-10-16 15:03:31 +02:00
evgeny 7454bebb14 Verify PipeWire node addressing with both cursor modes 2026-10-16 14:51:46 +02:00
evgeny ea971b0856 Preserve packed RGB formats and fix PipeWire test setup 2026-10-16 14:50:50 +02:00
evgeny 5725cfb686 Document PipeWire dependency and translate capture status 2026-10-16 14:38:45 +02:00
evgeny 3228cce0fb Test Wayland portal lifecycle and real PipeWire video delivery 2026-10-16 14:38:28 +02:00
evgeny 44c9c3bcaf Use native portal capture for Wayland broadcasts 2026-10-16 14:35:33 +02:00
evgeny ce0fa1f063 Add portal and PipeWire capture with embedded cursor support 2026-10-16 14:34:47 +02:00
evgeny cf3c8c7c34 Test X11 cursor placement and live visibility controls 2026-10-16 14:16:12 +02:00
evgeny ae1682bbe2 Document XFixes dependency and translate cursor controls 2026-10-16 14:14:37 +02:00
evgeny 7c1955f029 Add a persistent cursor toggle to X11 broadcast controls 2026-10-16 14:14:04 +02:00
evgeny 5753177f29 Include the cursor in X11 stream frames by default 2026-10-16 14:14:03 +02:00
evgeny e24ab45725 Add native X11 cursor composition for screen frames 2026-10-16 14:13:10 +02:00
evgeny d60f8e4b1b Preserve stream capture settings and refine audio playback 2026-10-16 14:05:54 +02:00
evgeny 198ebc0acb Restore the current preview when reopening stream controls 2026-10-16 14:02:30 +02:00
evgeny 00e9ed227a Capture the selected X11 monitor through QScreen 2026-10-16 14:00:56 +02:00
evgeny ac8e701406 Keep live capture bound to the selected monitor instance 2026-10-16 13:57:57 +02:00
evgeny 3d2f90e8ae Distinguish monitors with identical Qt screen names 2026-10-16 13:56:57 +02:00
evgeny 218249f9a5 Apply measured screen geometry through the GUI configuration path 2026-10-16 13:54:40 +02:00
evgeny 9bacde3bc1 Select proportional screen and advertised camera stream modes 2026-10-16 13:53:33 +02:00
evgeny 6228873ce2 Resolve desktop capture modes from source capabilities 2026-10-16 13:51:38 +02:00
evgeny ea46c56bc1 Define source-specific desktop stream video modes 2026-10-16 13:50:03 +02:00
evgeny bb5759728a Record live SM wake and reconnect verification on colo2 2026-10-16 13:12:01 +02:00
evgeny fc526d16c0 Test stream announcements after foreground wake and packet reordering 2026-10-16 12:55:10 +02:00
evgeny 919c3d76fe Fix peer standby cancellation on normal keepalive from a new link 2026-10-16 12:46:27 +02:00
evgeny 700034eec8 Add broadcast RS settings to desktop and Android 2026-10-16 09:49:58 +02:00
evgeny 6cdc2ce4dc Allow Android audio toggles during capture startup and test native control 2026-10-16 01:56:43 +02:00
evgeny 8f71a1161b Release stream radio suppression on END and test shared PCM mute 2026-10-16 01:55:28 +02:00
evgeny 7e7d86e4d3 Add Android live stream audio switch and document radio behavior 2026-10-16 01:54:32 +02:00
evgeny e3fb8377ab Track Android stream audio state independently of microphone ownership 2026-10-16 01:53:56 +02:00
evgeny c4fc4e9b1e Mute only the Android stream PCM branch during live publication 2026-10-16 01:52:31 +02:00
evgeny 25d27bfffe Add Android native control for source audio state 2026-10-16 01:51:37 +02:00
evgeny 559d66ae20 Test stream audio toggles and viewer scoped radio suppression 2026-10-16 01:49:30 +02:00
evgeny 2a572af2bb Label stream audio controls in English and Russian 2026-10-16 01:48:50 +02:00
evgeny e47ff579b3 Keep desktop stream mute controls synchronized with publication 2026-10-16 01:48:39 +02:00
evgeny f4d4b6033e Expose stream audio control to the desktop publisher 2026-10-16 01:48:39 +02:00
evgeny c9c1bb7cf1 Publish live audio toggles through the shared stream actor 2026-10-16 01:48:07 +02:00
evgeny db7264e271 Suppress source radio playback only while viewing audible streams 2026-10-16 01:47:44 +02:00
evgeny d14f9233ed Separate effective radio silence from stored member mute 2026-10-16 01:47:11 +02:00
evgeny 0f2e81bd0f Advertise stream audio state in signed source options 2026-10-16 01:46:39 +02:00
evgeny d766a50447 Keep Android capture ownership until device release and update busy messages 2026-10-16 01:34:37 +02:00
evgeny 829e4d41fa Document shared microphone ownership and test distinct desktop inputs 2026-10-16 01:29:55 +02:00
evgeny b523282e8e Allow simultaneous stream publication and radio in Android UI 2026-10-16 01:28:59 +02:00
evgeny 2038e33d8d Reset radio detector after Android capture queue discontinuities 2026-10-16 01:21:36 +02:00
evgeny 051d453c2d Validate Android input routes and isolate capture queue diagnostics 2026-10-16 01:20:34 +02:00
evgeny 9d69cce8e8 Connect Android stream and radio to shared capture and preserve stream audio mode 2026-10-16 01:18:26 +02:00
evgeny 4a49c830d1 Add bounded Android microphone subscriptions with independent ownership 2026-10-16 01:13:23 +02:00
evgeny d4eb1da233 Test shared microphone lifecycle and stream priority 2026-10-16 01:06:59 +02:00
evgeny 95942382bc Share desktop publisher microphone with radio while preserving stream format 2026-10-16 01:06:09 +02:00
evgeny 05ed516cf5 Use shared capture subscription for desktop radio 2026-10-16 01:05:14 +02:00
evgeny 6d7b3e8e02 Add shared desktop microphone sessions with stream profile priority 2026-10-16 00:25:25 +02:00
evgeny 7c5b76b482 Add minimized Windows autostart and preserve terminal output 2026-10-15 21:27:32 +02:00
evgeny abdca1acc7 Load chat background from embedded resources 2026-10-15 20:47:51 +02:00
evgeny 3e4d5d235f Isolate video call camera capture from the GUI process 2026-10-15 20:16:59 +02:00
evgeny 0b136ae2ab Fix Windows deployment classification of AVRT.dll 2026-10-15 18:55:35 +02:00
evgeny b88d76a8ab Fix Windows stream test and compact Android call diagnostics 2026-10-15 18:35:08 +02:00
evgeny 7477da42a5 Reduce Linux voice capture latency and verify device timing 2026-10-15 17:26:09 +02:00
evgeny 3276204196 docs: record live video flush latency and remaining clock gaps 2026-10-15 16:48:04 +02:00
evgeny 612fb7816d docs: record bounded video flush lifecycle and validation 2026-10-15 16:44:57 +02:00
evgeny 9886bc2fde call: continue bounded video flush without waiting for media ticks 2026-10-15 16:38:49 +02:00
evgeny ff51e30a55 Record final video timing measurements and identify fragment budget continuation gap 2026-10-15 16:30:13 +02:00
evgeny a373180c10 Document video playout timing contract tests and remaining live cadence issues 2026-10-15 16:24:02 +02:00
evgeny 717d965fec Keep Android wake deadlines absolute and report causes of the largest video gaps 2026-10-15 16:22:18 +02:00
evgeny 0d65c5bb74 Exercise delayed receive workers UI stalls and call restart with real video decoding 2026-10-15 16:14:51 +02:00
evgeny b211da9a04 Use shared video playout on Android without blocking decoder input while waiting 2026-10-15 16:13:48 +02:00
evgeny 5255133f27 Pace desktop call video independently and coalesce immediate UI publication 2026-10-15 15:58:33 +02:00
evgeny eb43876bb6 Timestamp video availability before receive worker scheduling 2026-10-15 15:57:05 +02:00
evgeny 408c0be021 Test video cadence against data stalls scheduler delays and audio corrections 2026-10-15 15:56:31 +02:00
evgeny 7f9eef8579 Add shared absolute video playout scheduler with bounded audio phase 2026-10-15 15:54:53 +02:00
evgeny 2ff14519fa Record measured desktop Android video latency and presentation timing limits 2026-10-15 15:25:07 +02:00
evgeny 24ba454821 Trace receive decode and UI publication for the reverse video direction 2026-10-15 15:18:35 +02:00
evgeny d7788b87ac Distinguish TextureView update notifications from committed frames 2026-10-15 15:18:35 +02:00
evgeny d1dae1ac2a Measure Android video decode audio wait and surface presentation separately 2026-10-15 15:06:24 +02:00
evgeny e2102bbbcc Trace sampled video frames through desktop encoding and transport 2026-10-15 15:04:51 +02:00
evgeny 19a135d552 Document live low latency route tests and Samsung headset MMAP fallback 2026-10-15 14:58:17 +02:00
evgeny 23c8a190dd Use AudioTrack for headsets whose physical MMAP routing is unreliable 2026-10-15 14:56:24 +02:00
evgeny 29b01237aa Keep call headset hotplug automatic after selecting speaker manually 2026-10-15 14:52:41 +02:00
evgeny 8add40ec00 Reopen call output on confirmed routes and recompute AEC from physical latency 2026-10-15 14:46:03 +02:00
evgeny a165372bbe Preserve device timestamp offsets across output reopen and counter wrap 2026-10-15 14:46:03 +02:00
evgeny 3226865ad7 Test route-local retry policy and output position continuity 2026-10-15 14:42:04 +02:00
evgeny 075ffc4d3b Add bounded AAudio voice output with AudioTrack fallback 2026-10-15 14:40:41 +02:00
evgeny a3854f2836 Allow call playback to invalidate a replaced hardware clock 2026-10-15 14:36:25 +02:00
evgeny f836ba67ce Expose device clock suspension without resetting jitter buffer 2026-10-15 14:36:25 +02:00
evgeny 0a56c01e29 Suspend hardware clock during output replacement without resetting media 2026-10-15 14:36:03 +02:00
evgeny ede911e7e4 Use bounded AAudio write pacing in probe and trace audio controls 2026-10-15 14:36:00 +02:00
evgeny 7a6ecf700c Trace headset endpoint changes and bound AAudio probe queue 2026-10-15 14:30:59 +02:00
evgeny 9d422dd798 Probe AAudio nonblocking writes alongside callback output 2026-10-15 14:27:21 +02:00
evgeny 43522936ff Record Android low latency output probe and route recovery results 2026-10-15 14:23:23 +02:00
evgeny e68df70aad Extend audio probe with route roundtrip and 40 ms control buffer 2026-10-15 14:19:03 +02:00
evgeny 11a3a20655 Add isolated Android AudioTrack and AAudio voice output probe 2026-10-15 14:14:48 +02:00
evgeny 9d948d399e Record live call results and Samsung voice output FAST rejection 2026-10-15 14:05:57 +02:00
evgeny 54e672420c Record measured output latency and validation of low-latency call output 2026-10-15 14:02:03 +02:00
evgeny 1a97219c43 Invalidate output measurements across concurrent Android route changes 2026-10-15 13:59:54 +02:00
evgeny b3ed8b06e7 Back off PCM reserve probes after starvation and exclude output pauses 2026-10-15 13:59:01 +02:00
evgeny 9c71115363 Localize output latency metrics and synchronize worker assertion 2026-10-15 13:57:41 +02:00
evgeny e1bb12d16a Expose desktop output latency and verify hardware clock transitions 2026-10-15 13:57:03 +02:00
evgeny 3083cc05dc Account for complete output callbacks and test adaptive PCM reserve 2026-10-15 13:56:38 +02:00
evgeny cfa3ed1f61 Adapt desktop call PCM reserve to output period and underruns 2026-10-15 13:55:49 +02:00
evgeny cb9852e8d5 Use Android low-latency output and presentation timestamps for call clocks 2026-10-15 13:55:49 +02:00
evgeny b6b0726bfe Document shared delay processing and verified frame alignment 2026-10-15 13:36:18 +02:00
evgeny c244808b77 Support Android C++11 in shared delay processor 2026-10-15 13:24:04 +02:00
evgeny b7b043777b Exercise network recovery and changing device block sizes 2026-10-15 13:23:28 +02:00
evgeny 26c91e6295 Test phase alignment after device silence and keep diagnostics current 2026-10-15 13:22:24 +02:00
evgeny 6896038f30 Include device silence in delay control timing 2026-10-15 13:20:50 +02:00
evgeny 22a03c5880 Report PCM mode, exact tempo and frame phase in call diagnostics 2026-10-15 13:19:39 +02:00
evgeny c1cc3c459b Specify jitter reserve at startup and expose delay diagnostics 2026-10-15 13:19:39 +02:00
evgeny aaff1a5494 Integrate delay processing with call jitter and verify PCM handoffs 2026-10-15 13:18:18 +02:00
evgeny 5f9262dd9a Register shared delay processor and its test target 2026-10-15 13:14:30 +02:00
evgeny 3f13860eac Align direct playback to source frames using bounded acceleration 2026-10-15 13:14:30 +02:00
evgeny 962067c2ac Add shared PCM delay processor with lossless mode boundaries 2026-10-15 13:10:45 +02:00
evgeny ff16adda17 Expose SoundTouch starvation with a 20 ms jitter reserve 2026-10-15 12:39:00 +02:00
evgeny f1aec9bb2d Lower shared call jitter reserve floor to 20 ms 2026-10-15 12:36:54 +02:00
evgeny 39c5274819 Record call teardown regression coverage and verified builds 2026-10-15 12:28:54 +02:00
evgeny 92f62a0121 Validate terminal call packets and document end acknowledgements 2026-10-15 12:26:40 +02:00
evgeny e6954b4152 Acknowledge call termination across router epoch changes 2026-10-15 12:24:55 +02:00
evgeny 3f41676a3d Define acknowledged call termination and enable route tracing 2026-10-15 12:18:47 +02:00
evgeny 59fb020711 Cancel stale video port commands and expose hangup regression 2026-10-15 12:15:07 +02:00
evgeny 1b07a8a708 Keep call metrics visible outside settings on both clients 2026-10-15 12:06:27 +02:00
evgeny 7d75afd4c5 Fix false queue-full detection in audio diagnostics 2026-10-15 11:52:07 +02:00
evgeny 233056a83a Document call latency measurements and capture period 2026-10-15 11:41:51 +02:00
evgeny 3c750d018c Measure Android capture age and device startup stages 2026-10-15 11:40:43 +02:00
evgeny 4cc7d5eaf4 Report call audio processing and send queue timing 2026-10-15 11:38:47 +02:00
evgeny 4476e875ab Measure call audio processing and send queue residence 2026-10-15 11:38:36 +02:00
evgeny dba813e8c5 Report desktop voice queue and capture processing latency 2026-10-15 11:36:58 +02:00
evgeny 96725caf03 Request 20 ms call capture and test output latency reports 2026-10-15 11:35:53 +02:00
evgeny 378d4103a8 Measure backend playback latency outside audio callbacks 2026-10-15 11:35:26 +02:00
evgeny 91030de5ea Cover immediate buffer probe failures and document tuning 2026-10-15 11:11:45 +02:00
evgeny 50bcf5539a Adapt Android call output buffer to device underruns 2026-10-15 11:10:08 +02:00
evgeny cbc7b296bb Add tested adaptive playback device buffer policy 2026-10-15 11:07:39 +02:00
evgeny 92a942ea8b Document continuous capture timing and device queue tuning scope 2026-10-15 03:37:45 +02:00
evgeny 80f6997e1b Keep capture PCM timestamps continuous across backend timing updates 2026-10-15 03:35:59 +02:00
evgeny 6765cf186d Handle headset routing and cancel pending endpoint requests on shutdown 2026-10-15 03:16:03 +02:00
evgeny d944418676 Test capture clock diagnostics and document routing ownership 2026-10-15 03:13:19 +02:00
evgeny 1da19276e5 Trace raw capture timing and PulseAudio latency without callback logging 2026-10-15 03:12:16 +02:00
evgeny a7c67ee488 Activate Telecom before call audio and adopt late connections 2026-10-15 03:11:45 +02:00
evgeny 9c4219d837 Use Telecom as the sole route owner for Android calls 2026-10-15 03:11:05 +02:00
evgeny a439b222da Bound Android call AudioTrack working buffer and pace PCM by device 2026-10-15 03:04:43 +02:00
evgeny a82c2ede6a Clarify audio diagnostic timing and reporter lifetime 2026-10-15 02:58:42 +02:00
evgeny b51e2c0817 Move AudioTrack diagnostic queries off playback and time operations separately 2026-10-15 02:58:42 +02:00
evgeny ac2029c82b Document audio trace fields and verify diagnostic reads preserve jitter events 2026-10-15 02:49:01 +02:00
evgeny c5efa56939 Move repetitive successful video key validation logs to trace 2026-10-15 02:47:45 +02:00
evgeny b4092d1bd6 Record bounded call audio traces and report event windows off playback thread 2026-10-15 02:47:33 +02:00
evgeny 39dbfa7673 Expose filtered Android call buffer diagnostics over JNI 2026-10-15 02:46:15 +02:00
evgeny f341d1db4b Provide call audio diagnostics without consuming stats events 2026-10-15 02:44:35 +02:00
evgeny e53ea2e04a Expose non-destructive jitter buffer diagnostic snapshots 2026-10-15 02:44:10 +02:00
evgeny d1cbb64884 Reduce Android call playback startup buffering and log output queue 2026-10-15 02:37:15 +02:00
evgeny 4c2d8aa4cc Prevent delayed camera startup from shifting video into the future 2026-10-15 02:32:35 +02:00
evgeny ac3801761e Keep video latency diagnostics within their clock domains 2026-10-15 02:29:34 +02:00
evgeny 15e4fcb710 Measure capture clock offset and video audio-barrier latency 2026-10-15 02:29:09 +02:00
evgeny 4447f25e37 Record live camera FPS diagnosis and guard ownership 2026-10-15 02:21:16 +02:00
evgeny f84b24806e Keep UVC camera frame rate stable during video calls 2026-10-15 02:20:32 +02:00
evgeny 459b1ecc01 Display every new desktop call preview frame 2026-10-15 02:18:54 +02:00
evgeny 55293483da Document video timeout diagnosis and independent Android rotation 2026-10-15 02:14:14 +02:00
evgeny fc0559c974 Preserve fractional frame budget when downsampling cameras 2026-10-15 02:13:42 +02:00
evgeny f8e960c844 Retain jitter tolerance across desktop camera phase drift 2026-10-15 02:12:16 +02:00
evgeny 5666da8859 Bound Android bitrate wait by requested keyframe cadence 2026-10-15 02:11:45 +02:00
evgeny 0c214dfca0 Rotate call video independently of Android call controls 2026-10-15 02:11:23 +02:00
evgeny 78246e249e Document measured call FPS loss and bounded audio synchronization queue 2026-10-15 02:07:04 +02:00
evgeny fe2ccb07e1 Keep 60 fps downsampling away from half-period ties 2026-10-15 02:05:29 +02:00
evgeny ee9af6533d Avoid accumulated rounding in call frame pacing 2026-10-15 02:05:08 +02:00
evgeny f3eed42c3f Preserve desktop camera cadence under timestamp jitter 2026-10-15 02:04:26 +02:00
evgeny 209f2ceb7c Queue video frames while awaiting matching audio timestamps 2026-10-15 02:04:25 +02:00
evgeny 95ab911caf Track desktop video frame flow and update call preview geometry 2026-10-15 01:59:59 +02:00
evgeny b665191b9e Render Android call camera preview directly through Camera2 2026-10-15 01:59:42 +02:00
evgeny 572392511b Measure call video throughput and audio gating losses 2026-10-15 01:58:25 +02:00
evgeny 4f91f575a1 Document Android call video navigation and preview limits 2026-10-15 01:53:47 +02:00
evgeny 5cd2df9125 Opt in to stable system bar inset measurements 2026-10-15 01:53:12 +02:00
evgeny 964c17f1bf Add Android call controls navigation and expandable video thumbnails 2026-10-15 01:52:38 +02:00
evgeny 64f1fe4dfb Add call video navigation labels 2026-10-15 01:51:35 +02:00
evgeny 129f809b7b Ignore stale proximity events after listener replacement 2026-10-15 01:44:08 +02:00
evgeny e7ff764ed0 Document video orientation and proximity-gated speaker activation 2026-10-15 01:43:24 +02:00
evgeny f61e1c0a9f Defer video speaker activation until the phone is away from the ear 2026-10-15 01:42:17 +02:00
evgeny 1b3d9ff8ee Distinguish unknown proximity from confirmed far before speaker changes 2026-10-15 01:42:17 +02:00
evgeny 97e3b3e9ef Match Android call screen orientation to the received video 2026-10-15 01:39:08 +02:00
evgeny a58cfcedc6 Document separate video and call controls windows 2026-10-15 01:37:11 +02:00
evgeny 170a6b0d57 Translate separate call video window actions 2026-10-15 01:36:33 +02:00
evgeny 9f8fb64e6e Show call video in a separate resizable desktop window 2026-10-15 01:36:14 +02:00
evgeny 401ca96d7d Record hardware bitrate verification and final call video checks 2026-10-15 01:31:40 +02:00
evgeny e1b29af8ce Keep queued video frames during in-place bitrate changes 2026-10-15 01:30:55 +02:00
evgeny 1376f9f059 Validate bitrate ceilings and recovery without requiring filler data 2026-10-15 01:29:20 +02:00
evgeny eeb3ca5927 Avoid uncached per-pixel chroma writes in codec probe 2026-10-15 01:26:35 +02:00
evgeny 5e22da3098 Document call video layout and clock discontinuity fixes 2026-10-15 01:25:22 +02:00
evgeny 13feaca674 Use bounded contrast and bulk YUV writes in hardware rate probe 2026-10-15 01:23:34 +02:00
evgeny 607952b709 Verify hardware rate changes on continuous noisy video 2026-10-15 01:14:27 +02:00
evgeny 1b0b429835 Exercise asynchronous rate changes with continuous video output 2026-10-15 01:13:54 +02:00
evgeny 0dec628e49 Prepare call video bitrate encoders without pausing capture 2026-10-15 01:13:36 +02:00
evgeny 152d89f0dc Apply Android call bitrate changes in place on validated keyframes 2026-10-15 01:11:02 +02:00
evgeny 8582d2e2b0 Log call video surface lifetime and preview visibility 2026-10-15 00:50:36 +02:00
evgeny 5c6f71c602 Keep Camera2 frames when timestamp jitter crosses nominal frame duration 2026-10-15 00:49:52 +02:00
evgeny 6ff21c12ef Regress video playback across repeated audio clock epoch changes 2026-10-15 00:49:08 +02:00
evgeny b1390a9542 Ignore stale Android call surfaces during activity replacement 2026-10-15 00:48:12 +02:00
evgeny 1c5ef12c8f Keep call display format internal to the Android application 2026-10-15 00:47:42 +02:00
evgeny b6961f5fbc Localize Android call video settings 2026-10-15 00:46:38 +02:00
evgeny 2db038beee Separate Android full screen call video from controls and settings 2026-10-15 00:46:26 +02:00
evgeny 898154b2b6 Keep desktop video in a resizable window and retain decoder on audio clock updates 2026-10-15 00:45:22 +02:00
evgeny 21c22bd911 Preserve Android video decoder across audio clock corrections and expose previews 2026-10-15 00:44:45 +02:00
evgeny a0db643acb Place camera thumbnail inside remote picture and document call layout 2026-10-15 00:34:07 +02:00
evgeny 87a2075dec Keep call diagnostics in settings and translate video controls 2026-10-15 00:32:40 +02:00
evgeny 434b59b1c7 Show remote calls full screen with camera picture in picture 2026-10-15 00:31:50 +02:00
evgeny 4a7d64b2aa Expose call camera preview and clear inactive remote video 2026-10-15 00:31:03 +02:00
evgeny 21ab48b6c3 Document desktop call encoder locale regression and validation 2026-10-15 00:07:07 +02:00
evgeny ef397a6b48 Fix call encoder levels under comma decimal locales 2026-10-15 00:06:20 +02:00
evgeny faee775dff Record the incomplete cross-device AVC decoder probe accurately 2026-10-14 23:45:34 +02:00
evgeny 8b4b278f3c Document the corrected video contract and verified hardware matrix 2026-10-14 23:45:01 +02:00
evgeny 61bcf28720 Verify Android hardware bitstreams through the production Qt decoder 2026-10-14 23:40:48 +02:00
evgeny 5d115c3dac Add cross-device decoding to the explicit debug video probe 2026-10-14 23:40:47 +02:00
evgeny 6910e07c31 Surface failed video configuration and camera capture stalls 2026-10-14 23:40:01 +02:00
evgeny 5f16c79559 Preserve bitrate bounds on format changes and discard late desktop pictures 2026-10-14 23:19:18 +02:00
evgeny 047927a7a5 Check VPS HRD and log actual codec constraints on rejection 2026-10-14 23:19:18 +02:00
evgeny 005d891fb4 Bound video send debt and test decoder acceptance and rejection 2026-10-14 23:18:40 +02:00
evgeny 634ef222a4 Fallback desktop video on decoder rejection and verify receive-only codecs 2026-10-14 23:17:25 +02:00
evgeny f47b7167a2 Fallback Android video after explicit decoder rejection 2026-10-14 23:16:55 +02:00
evgeny 8703e2678a Expose remote video decoder acceptance to Android workers 2026-10-14 23:16:55 +02:00
evgeny afe9437c49 Deliver decoder results through the thread-safe call video port 2026-10-14 23:16:20 +02:00
evgeny d32c8ed6e3 Report decoder acceptance separately from keyframe recovery 2026-10-14 23:16:20 +02:00
evgeny 31a0c4f1a3 Validate HEVC progressive VUI and signaled HRD limits 2026-10-14 23:15:12 +02:00
evgeny aad77cf415 Share normative HRD limits with the bitstream validator 2026-10-14 23:15:11 +02:00
evgeny ea5ef4abc2 Probe hardware rate transitions and clear stale call port commands 2026-10-14 23:13:45 +02:00
evgeny 96e8f6c0ac Test real decoder fixtures and malformed video parameter sets 2026-10-14 23:13:25 +02:00
evgeny 2f1de49e87 Negotiate actual Android modes and replace single encoder on IDR 2026-10-14 23:13:01 +02:00
evgeny fe16509293 Advertise desktop decoder capabilities independently of encoders 2026-10-14 23:12:15 +02:00
evgeny 47cca28d39 Probe Android encoders and decoders independently with actual formats 2026-10-14 23:12:00 +02:00
evgeny 4eece00a2d Add independent AVC and HEVC decoder probe bitstreams 2026-10-14 23:11:00 +02:00
evgeny 5e15fc0d3f Expose common bitstream inspection and actual format checks to Android 2026-10-14 23:10:12 +02:00
evgeny 68e5905d9e Adapt call transport tests and desktop setup to profile negotiation 2026-10-14 23:09:51 +02:00
evgeny 3063270a67 Cover directional profiles and normative DPB limits in video tests 2026-10-14 23:09:30 +02:00
evgeny c7184b55d8 Validate desktop call IDRs with the common bitstream contract 2026-10-14 23:08:47 +02:00
evgeny ce2560ef4b Wire shared video validator and log negotiated profiles 2026-10-14 23:08:46 +02:00
evgeny 53c6437301 Add shared video parameter set and independent IDR validation 2026-10-14 23:08:10 +02:00
evgeny 520f7a29a7 Separate video profiles and network bitrate from encoder VBV 2026-10-14 23:06:40 +02:00
evgeny a06bbc34df Record platform video integration and verified hardware contract blockers 2026-10-14 22:52:15 +02:00
evgeny b2c6500fea Test platform video port over a real bidirectional call transport 2026-10-14 22:50:25 +02:00
evgeny b01d54a431 Request constrained AVC explicitly and diagnose hardware SPS limits 2026-10-14 22:49:31 +02:00
evgeny 156b250432 Exercise production call decoder across real bitrate transitions 2026-10-14 22:46:18 +02:00
evgeny 9becdac331 Add explicit device instrumentation for call codec verification 2026-10-14 22:46:10 +02:00
evgeny ba2a66341a Add Android call video display and live camera codec bitrate controls 2026-10-14 22:45:34 +02:00
evgeny a59ebcd6db Own Android call video in the foreground call service 2026-10-14 22:45:34 +02:00
evgeny 04f4d29e4f Add Android call camera and keyframe encoder replacement worker 2026-10-14 22:44:32 +02:00
evgeny edf7e4d2c5 Render Android call video against the audio playback clock 2026-10-14 22:43:12 +02:00
evgeny 5dbc5bcf59 Probe Android call encoders through real YUV encode and decode 2026-10-14 22:42:16 +02:00
evgeny c986221cb6 Expose shared video negotiation and bounded queues to Android JNI 2026-10-14 22:40:48 +02:00
evgeny d01bc395fa Use current FFmpeg profile constants and qualify video port status 2026-10-14 22:39:56 +02:00
evgeny af35d03399 Add live call video controls and display to the desktop call window 2026-10-14 22:39:13 +02:00
evgeny e682f30ca9 Expose active call bitrate range through the shared video port 2026-10-14 22:38:39 +02:00
evgeny cabae34791 Connect desktop camera workers to negotiated call video and audio clock 2026-10-14 22:37:50 +02:00
evgeny b091aa0df2 Decode call video with bounded input and verified output metadata 2026-10-14 22:36:32 +02:00
evgeny 57a59df983 Bind shared call video port to desktop and Android core lifetime 2026-10-14 22:36:03 +02:00
evgeny 5e37aaa2fb Add bounded cross-thread video port for platform call workers 2026-10-14 22:35:25 +02:00
evgeny 65d7ec875e Record final codec envelope builds and regression results 2026-10-14 22:27:48 +02:00
evgeny 78d3511174 Document negotiated video envelopes and remaining platform integration 2026-10-14 22:27:16 +02:00
evgeny f055f8a9df Use fresh capture PTS after discarded video and diagnose rejected frames 2026-10-14 22:22:02 +02:00
evgeny 8c12dfc02f Verify pending video is discarded when peer capabilities shrink 2026-10-14 22:14:30 +02:00
evgeny ea65d87ec1 Round-trip real codecs using the negotiated level and reject invalid envelopes 2026-10-14 22:10:42 +02:00
evgeny 3f61549769 Open desktop call encoders from the shared negotiated video format 2026-10-14 22:10:21 +02:00
evgeny 534f319d86 Test directional codec envelopes and reject out-of-cap video in live calls 2026-10-14 22:08:48 +02:00
evgeny fa53139163 Bind call rate control and frame admission to negotiated codec envelopes 2026-10-14 22:07:04 +02:00
evgeny d4e6bc5980 Negotiate call video level and bitrate VBV envelopes in the shared protocol 2026-10-14 22:05:55 +02:00
evgeny 2a22d625e1 Record validated desktop call encoder and remaining integration boundaries 2026-10-14 22:01:47 +02:00
evgeny cab992228c Preserve explicit VBV and report inactive call encoder state 2026-10-14 21:57:58 +02:00
evgeny 0f570edbd0 Exercise real H264 and H265 calls across delayed bitrate switches 2026-10-14 21:55:11 +02:00
evgeny 327478475c Bound encoder rate requests by the negotiated mode ceiling 2026-10-14 21:46:53 +02:00
evgeny 3b3ba3c495 Add verified call profiles and defer bitrate replacement until IDR 2026-10-14 21:46:13 +02:00
evgeny 43a90ff23b Build shared live video library independently from stream publication 2026-10-14 21:44:16 +02:00
evgeny 45720ebaba Use shared live encoder types in stream publication 2026-10-14 21:44:16 +02:00
evgeny dca1adc173 Extract live video encoder naming for reuse by calls and broadcasts 2026-10-14 21:43:54 +02:00
evgeny f89494fb4f Specify deferred bitrate changes and validate IDR before releasing old encoder 2026-10-14 21:39:24 +02:00
evgeny abf7ccf566 Probe x265 bitrate switching at scheduled IDR with encoder replacement 2026-10-14 21:38:05 +02:00
evgeny e20f4113a4 Record x265 reconfiguration defect and validated dependency patch 2026-10-14 21:33:41 +02:00
evgeny 5d8c6b8ff3 Add measured x265 bitrate adaptation probe for call backends 2026-10-14 21:32:02 +02:00
evgeny 4b414deb6e Record successful bitrate range regression checks 2026-10-14 21:21:21 +02:00
evgeny a6b8594219 Document call bitrate range settings and validation 2026-10-14 21:19:11 +02:00
evgeny 6980bc7a88 Expose the adaptive call video range in Android audio settings 2026-10-14 21:17:46 +02:00
evgeny cc341221d4 Verify live bitrate range changes and incompatible codec limits 2026-10-14 21:10:12 +02:00
evgeny f04e3fd995 Persist the Android call video bitrate range atomically 2026-10-14 21:10:12 +02:00
evgeny 6cbb13d11d Translate call bitrate range settings 2026-10-14 21:08:13 +02:00
evgeny 0fe9a779f0 Add call video bitrate range controls to desktop settings 2026-10-14 21:07:50 +02:00
evgeny 03d8f71be4 Test video adaptation from poor connectivity to the 4 Mbps ceiling 2026-10-14 21:07:08 +02:00
evgeny 4abc5ef6e7 Apply live call bitrate range within the codec ceiling 2026-10-14 21:06:26 +02:00
evgeny 5789a83ea2 Define atomic call video bitrate range with 300–4000 kbps defaults 2026-10-14 21:06:07 +02:00
evgeny 6b409a5006 Record video transport validation and codec negotiation gap 2026-10-14 20:59:51 +02:00
evgeny ed848f94eb Bound video encoder commands and verify generation-safe feedback 2026-10-14 20:53:53 +02:00
evgeny 23bd954b79 Drive call video rate control from endpoint delivery snapshots 2026-10-14 20:52:41 +02:00
evgeny 2c9904c345 Handle video capability exchange racing with call acceptance 2026-10-14 20:50:32 +02:00
evgeny 996d4a89f5 Exercise video switching and backpressure in a real call 2026-10-14 20:49:54 +02:00
evgeny b466ec30e3 Acknowledge video capabilities before sending frame data 2026-10-14 20:48:58 +02:00
evgeny 609221e384 Separate call audio and video from signaling queues 2026-10-14 20:48:27 +02:00
evgeny 14a56d9b33 Add bounded call video transport and capability exchange 2026-10-14 20:47:44 +02:00
evgeny dffde9691d Share call session ownership with the video transport 2026-10-14 20:46:02 +02:00
evgeny b00c6a2b6d Test call video negotiation and frame wire boundaries 2026-10-14 20:44:42 +02:00
evgeny c8bbce6a94 Define call video capabilities and bounded frame assembly 2026-10-14 20:43:42 +02:00
evgeny 5fbea21482 Record call clock validation results 2026-10-14 19:42:56 +02:00
evgeny 120a865152 Record the implemented call timing protocol and next stages 2026-10-14 19:42:32 +02:00
evgeny 610773fa90 Document and log the call source clock contract 2026-10-14 19:38:59 +02:00
evgeny 4a55c30f95 Verify capture clock metadata over the call transport 2026-10-14 19:37:25 +02:00
evgeny a978bb7b06 Exercise call clocks through Opus and jitter recovery 2026-10-14 19:36:51 +02:00
evgeny e975d24a73 Track Android call capture and playback clocks 2026-10-14 19:36:11 +02:00
evgeny 023f3a335e Pass call audio timing across Android JNI 2026-10-14 19:36:11 +02:00
evgeny 9fe5cd4c27 Test call capture timestamps and device progress 2026-10-14 19:35:56 +02:00
evgeny c041882f5f Observe capture timestamps and device progress in voice tests 2026-10-14 19:30:28 +02:00
evgeny 0195732b4e Keep call audio regressions explicit about untimed sources 2026-10-14 19:29:05 +02:00
evgeny 2f3eb66c4c Preserve measured versus estimated device timing in voice mixer 2026-10-14 19:29:04 +02:00
evgeny 39bfedca86 Drive desktop call clock from rendered PCM and capture timing 2026-10-14 19:28:38 +02:00
evgeny 7bac999d93 Handle source discontinuities and reject stale device epochs 2026-10-14 19:27:54 +02:00
evgeny 9aba8e278c Preserve capture PTS and expose call playback clock to platforms 2026-10-14 19:27:03 +02:00
evgeny ab283eebdc Expose measured Opus codec delay for capture clock mapping 2026-10-14 19:26:09 +02:00
evgeny 96e7983128 Attach source PTS maps to call jitter and playback epochs 2026-10-14 19:25:30 +02:00
evgeny dc3cf4f227 Update call transport tests for explicit capture metadata 2026-10-14 19:24:51 +02:00
evgeny 2e1908a52b Preserve capture clock across call delivery and validate media peer 2026-10-14 19:24:51 +02:00
evgeny ab04b14237 Carry capture timestamps and Opus delay in call media protocol 2026-10-14 19:24:22 +02:00
evgeny fe2fa73cc0 Test audio timeline boundaries and sustained SoundTouch playback 2026-10-14 19:23:40 +02:00
evgeny 991d6bad43 Map produced audio to source PTS and bounded device progress 2026-10-14 19:22:32 +02:00
evgeny b5bd45c4da Define bounded audio timeline and playback clock contracts 2026-10-14 19:21:20 +02:00
evgeny 4939ee7fb0 Account for transposer prefill in source coordinates 2026-10-14 19:19:50 +02:00
evgeny 811b980883 Verify exact SoundTouch provenance and unchanged PCM output 2026-10-14 19:17:46 +02:00
evgeny 1d43578335 Expose optional live source tracking through SoundTouch 2026-10-14 19:16:45 +02:00
evgeny edcd34d942 Report copied and overlapping source ranges from TDStretch 2026-10-14 19:16:03 +02:00
evgeny ceb06bafcf Define SoundTouch source spans and unity interpolation contract 2026-10-14 19:15:43 +02:00
evgeny 183e66e97d Record video foundation checks and unresolved audio clock contract 2026-10-14 18:46:57 +02:00
evgeny d441d9634d Document measured SoundTouch clock drift before video integration 2026-10-14 18:44:15 +02:00
evgeny 05d9e3f22e Check SoundTouch source time against identifiable audio samples 2026-10-14 18:42:46 +02:00
evgeny 801050bacb Exercise video rate feedback with simulated channel changes 2026-10-14 18:41:33 +02:00
evgeny f24a8ca6d3 Add video bitrate regulator with bounded debt feedback 2026-10-14 18:40:35 +02:00
evgeny 0bbd4d6c34 Verify router ACK accounting across retries and epoch resets 2026-10-14 18:34:33 +02:00
evgeny 6a1e7a90dd Record video call implementation contracts and milestones 2026-10-14 18:33:42 +02:00
evgeny 859bb733af Build and test router delivery history boundaries 2026-10-14 18:33:05 +02:00
evgeny f87c6a93bc Expose per-service payload backlog and acknowledged delivery 2026-10-14 18:32:28 +02:00
evgeny 61faca84d7 Add aligned router delivery metering for video adaptation 2026-10-14 18:31:52 +02:00
evgeny 0de5479e8e Document live zoom validation and intermittent STCP test failure 2026-10-14 17:44:51 +02:00
evgeny 8eef506eed Enable pinch zoom and bounded panning in Android live viewer 2026-10-14 17:41:12 +02:00
evgeny c39610f079 Share video zoom geometry between Android viewers 2026-10-14 17:36:38 +02:00
evgeny 7ff95623c1 Document fullscreen live viewer behavior and SM checks 2026-10-14 17:31:08 +02:00
evgeny 931631a4a9 Show Android live streams fullscreen with automatic orientation and timed controls 2026-10-14 17:28:16 +02:00
evgeny d912d53979 Record SM audio playback validation and native snapshot test flake 2026-10-14 17:21:10 +02:00
evgeny ded0d401c7 Match stream audio queue to device buffer and document playback ownership 2026-10-14 17:19:04 +02:00
evgeny 0fdc6e435b Fix Android stream audio backpressure without blocking video 2026-10-14 17:16:45 +02:00
evgeny 91d1a7994e Record stream role lookup measurements and architecture decisions 2026-10-14 16:52:31 +02:00
evgeny a4f508feed Read stream supernode role directly by member ID 2026-10-14 16:49:40 +02:00
evgeny d2f8e57118 Record keyframe recovery fixes and remaining architecture review 2026-10-14 16:34:30 +02:00
evgeny 7dd1176545 Document complete keyframe admission and shared media opening 2026-10-14 16:32:15 +02:00
evgeny 97fea6e809 Use shared media opening in desktop and Android viewers 2026-10-14 16:30:38 +02:00
evgeny 1809416dce Add atomic media reader opening with selected epoch validation 2026-10-14 16:26:41 +02:00
evgeny d75aea1a09 Remove unused media receiver and test the shared ring cursor 2026-10-14 16:24:32 +02:00
evgeny d209ab94ba Gate media cursor revision changes on a complete keyframe 2026-10-14 16:22:15 +02:00
evgeny afa8fd307a Reproduce media cursor revision admission inconsistency 2026-10-14 16:10:26 +02:00
evgeny 84472cc276 Clarify stream bootstrap and log bounded publisher drain 2026-10-14 16:05:17 +02:00
evgeny d0ddc9ae8c Fix partial stream bootstrap and release drained upstream flows 2026-10-14 16:02:24 +02:00
evgeny 1815de059e Record direct preview verification and camera teardown ownership 2026-10-14 15:58:31 +02:00
evgeny 12ad2bf14b Release all preview session outputs when the camera device closes 2026-10-14 15:44:08 +02:00
evgeny 117087d56b Distinguish camera preview failure from a stopped stream 2026-10-14 15:43:24 +02:00
evgeny 2ee3103c8c Avoid double sensor rotation in direct Android camera preview 2026-10-14 15:43:24 +02:00
evgeny b8a2d7a555 Detach direct camera preview immediately when UI goes to background 2026-10-14 15:30:03 +02:00
evgeny 78054b2c1d Measure direct preview frame age using camera timestamp clocks 2026-10-14 15:19:49 +02:00
evgeny 30dae7d7ed Document direct Android camera preview and surface ownership 2026-10-14 15:14:42 +02:00
evgeny 548e64c963 Use direct camera preview instead of a local stream decoder 2026-10-14 14:58:03 +02:00
evgeny e8a63ec40d Send Android camera frames directly to preview surfaces 2026-10-14 14:58:03 +02:00
evgeny 5630bedc51 Record verified AV1 playback fix and regression coverage 2026-10-14 14:25:20 +02:00
evgeny 9ef18b6324 Release Android inflight state at decoder EOS before audio tail 2026-10-14 14:17:35 +02:00
evgeny 7b4dfc062a Document demand driven playback and delayed decoder lifecycle 2026-10-14 14:10:36 +02:00
evgeny 8d0504c759 Exercise codec output delay explicitly in the desktop fixture 2026-10-14 14:04:45 +02:00
evgeny 5ce2877fc0 Bound desktop codec work and drain delayed frames through EOF 2026-10-14 13:57:58 +02:00
evgeny c02222610b Preserve observed decoder lead while its pipeline drains 2026-10-14 13:49:57 +02:00
evgeny 360a6efafc Verify outstanding read replies and explicit video demand 2026-10-14 13:49:14 +02:00
evgeny 74c96ba5e9 Let desktop codecs read ahead while keeping presentation bounded 2026-10-14 13:43:23 +02:00
evgeny 049480408a Test frozen clock decoding and single Android read responses 2026-10-14 13:37:43 +02:00
evgeny 31b10435d3 Use explicit video demand in ring and network reader tests 2026-10-14 13:36:38 +02:00
evgeny 9331c26b22 Distinguish Android decoder startup from waiting for a keyframe 2026-10-14 13:36:38 +02:00
evgeny f72e2fca94 Drive Android decoding by codec readiness and bounded working frames 2026-10-14 13:36:38 +02:00
evgeny 223c9a153c Request the next video frame through JNI without a time horizon 2026-10-14 13:36:38 +02:00
evgeny 5a3999fbdb Prepare one Android media response per player request 2026-10-14 13:36:38 +02:00
evgeny ac339bb61f Prepare one desktop media response per player request 2026-10-14 13:27:10 +02:00
evgeny 33f8dacbfc Expose demand driven video reads through the stream handle 2026-10-14 13:25:50 +02:00
evgeny f317d3e989 Read the next live video frame independently of presentation time 2026-10-14 13:25:50 +02:00
evgeny 47119c73a4 Record completed desktop broadcast implementation and checks 2026-10-14 13:00:15 +02:00
evgeny 4e7b8f5c1a Keep desktop stream failure visible after draining 2026-10-14 12:58:09 +02:00
evgeny c3512b787e Test fatal desktop audio failure after successful capture 2026-10-14 12:56:49 +02:00
evgeny 470001bbab End desktop publication on fatal audio worker failure 2026-10-14 12:56:26 +02:00
evgeny b25070acbd Document shared live publisher and desktop capture lifecycle 2026-10-14 12:54:44 +02:00
evgeny e99a1b9450 Verify live desktop codec changes preserve the audio epoch 2026-10-14 12:53:24 +02:00
evgeny b5f84d4a9b Include complete video frame type in the raw preview integration test 2026-10-14 12:45:44 +02:00
evgeny 16dc3a13aa Verify live bitrate decoder continuity and capture installer completeness 2026-10-14 12:41:56 +02:00
evgeny 8fda2b0751 Format the isolated encoder capability and live setup passes 2026-10-14 12:38:41 +02:00
evgeny 7ad0aa61af Update live x264 bitrate and exclude encoders without forced key support 2026-10-14 12:32:33 +02:00
evgeny e4f9a48c2c Reuse static screen frames across encoder changes and test rollback 2026-10-14 12:27:50 +02:00
evgeny c08415a255 Translate capture termination and frame conversion errors 2026-10-14 12:11:36 +02:00
evgeny 2caa9504c9 Report capture termination and preserve explicit microphone selection 2026-10-14 12:11:36 +02:00
evgeny ee54626de9 Describe own stream management and system screen selection 2026-10-14 12:08:01 +02:00
evgeny 80bd17a28e Open own broadcast controls and keep rejected voice recording idle 2026-10-14 12:08:01 +02:00
evgeny ba17f9908d Render raw preview at 30 fps and preserve fallback audio sample timing 2026-10-14 12:06:45 +02:00
evgeny 27f3726124 Inspect capture plugin dependencies and recognize XWayland sessions 2026-10-14 11:49:04 +02:00
evgeny 97c460e2f1 Observe capture activation raw frames and encoder generations 2026-10-14 11:44:11 +02:00
evgeny 945c75ea07 Install capture dependencies and verify Multimedia plugin deployment 2026-10-14 11:26:50 +02:00
evgeny 7f7bb1c939 Verify forced keyframes and isolate encoder probes from live timestamps 2026-10-14 11:25:38 +02:00
evgeny 7720b7036d Deploy Qt Multimedia dependencies with Windows broadcasts 2026-10-14 11:21:48 +02:00
evgeny 1b85406b13 Trace encoder responses to explicit random access frame requests 2026-10-14 11:21:11 +02:00
evgeny f85f45fbd3 Validate publisher lifecycle in optional codec builds 2026-10-14 10:21:40 +02:00
evgeny 4a4397ace1 Start portal encoder deadlines after the first permitted capture frame 2026-10-14 10:20:50 +02:00
evgeny 240568870a Test desktop codec round trips and real screen publication 2026-10-14 10:19:44 +02:00
evgeny 29313cce54 Reserve broadcast capture exclusively while preserving shared voice I/O 2026-10-14 10:17:48 +02:00
evgeny 386998598e Restore bitrate controls and wait for explicit portal source selection 2026-10-14 02:58:45 +02:00
evgeny d934978fb2 Translate desktop broadcast controls and capture diagnostics 2026-10-14 02:57:56 +02:00
evgeny ce461521e4 Defer source failures and end calls that cannot reserve audio capture 2026-10-14 02:56:36 +02:00
evgeny 50fad4ceff Preserve video color range and handle capture worker failures 2026-10-14 02:55:36 +02:00
evgeny ce46677dfb Keep voice recording from opening an already owned microphone 2026-10-14 02:54:30 +02:00
evgeny b3c698be25 Prevent radio capture from competing with a broadcast microphone 2026-10-14 02:54:20 +02:00
evgeny c1d7460254 Own publication independently of its window and reserve call capture 2026-10-14 02:54:19 +02:00
evgeny ab01c6dc48 Expose broadcast setup even when a channel has no live sources 2026-10-14 02:53:22 +02:00
evgeny c91bb2828f Keep raw preview and source permissions independent of video encoding 2026-10-14 02:52:36 +02:00
evgeny f96443e1a6 Add desktop broadcast controls and aggregate send indicators 2026-10-14 02:51:41 +02:00
evgeny 701a7d0eac Capture camera screen and stereo microphone for desktop publication 2026-10-14 02:49:12 +02:00
evgeny 0055b86b19 Encode low latency desktop video with codec specific keyframes 2026-10-14 02:44:59 +02:00
evgeny 77acdb2d65 Expose radio compressor settings to publication workers 2026-10-14 02:35:55 +02:00
evgeny 125f740a5f Use the shared publisher in Android and desktop stream bridges 2026-10-14 02:34:16 +02:00
evgeny f5d112a712 Share bounded media publication and send telemetry across frontends 2026-10-14 02:32:14 +02:00
evgeny a5f8b8431d Verify video profile fallback without excluding a supported codec 2026-10-14 02:14:24 +02:00
evgeny 499ce21cfc Use available encoder profiles when the preferred video profile is absent 2026-10-14 02:14:24 +02:00
evgeny 643420b644 Record codec and telemetry validation with precise decoder diagnostics 2026-10-14 02:11:59 +02:00
evgeny 49ca49fa1e Assemble partial codec setup and test real out of band decoder configuration 2026-10-14 02:01:44 +02:00
evgeny b4aeb1a3fd Keep preview layout stable and document codec configuration exchange 2026-10-14 01:56:02 +02:00
evgeny 39297d1a07 Explain unavailable video decoders and restored capture settings 2026-10-14 01:47:32 +02:00
evgeny de67de33df Report codec capabilities and document the expanded Android media header 2026-10-14 01:45:50 +02:00
evgeny bf12bd5b05 Count only current viewer media against the preparation limit 2026-10-14 01:43:44 +02:00
evgeny 990713c7a7 Retain complete codec parameter sets across separate configuration callbacks 2026-10-14 01:41:12 +02:00
evgeny a4e6683c5b Exercise modern codec playback and partial video queue telemetry 2026-10-14 01:32:40 +02:00
evgeny 06bd9947ce Test codec keyframes and bitrate selection across camera changes 2026-10-14 01:21:04 +02:00
evgeny 305eacbe95 Verify all media codec IDs and key configuration bounds 2026-10-14 01:20:00 +02:00
evgeny 876a5a65ec Test aggregate send windows with duplicate ACKs and connection teardown 2026-10-14 01:20:00 +02:00
evgeny 3e7197702b Decode all supported video formats from uAV2 on desktop 2026-10-14 01:14:38 +02:00
evgeny c815d06ab0 Add video codec and bitrate controls with aggregate send buffer indicators 2026-10-14 01:13:28 +02:00
evgeny 7a5a94bb64 Keep ten hertz publication telemetry separate from preview state 2026-10-14 01:12:31 +02:00
evgeny 1ac7a40432 Capture and play codec specific access units with live bitrate changes 2026-10-14 01:11:49 +02:00
evgeny d209049f71 Enumerate supported surface encoders and model codec specific keyframes 2026-10-14 01:10:43 +02:00
evgeny 5677e8ec5f Initialize the publication media format with the selected codec 2026-10-14 01:09:30 +02:00
evgeny cd8a5392d5 Expose source codec selection and aggregate send telemetry through JNI 2026-10-14 01:09:30 +02:00
evgeny 8b6c72b704 Publish bounded 100 ms send telemetry from the Android media actor 2026-10-14 01:08:20 +02:00
evgeny 4d03a2db53 Expose pending source deliveries without counting ETCP inflight twice 2026-10-14 01:06:57 +02:00
evgeny b6652c7c7f Record unique acknowledged packets at the instance transport boundary 2026-10-14 01:06:56 +02:00
evgeny ac89601fc5 Add instance lifetime ACK windows and exclusive ETCP send queue snapshots 2026-10-14 01:06:32 +02:00
evgeny 7e693fcc97 Define uAV2 codec IDs and signed keyframe configuration envelopes 2026-10-14 01:06:32 +02:00
evgeny 84246bea89 Record adaptive playback validation and ring reader lifecycle 2026-10-14 00:13:08 +02:00
evgeny 2aafe172d6 Reject large audio timestamp jumps before narrowing PLC packet counts 2026-10-14 00:11:31 +02:00
evgeny 359770ecb4 Await all relay ACCEPTs through the bounded pending-buffer retry 2026-10-14 00:09:12 +02:00
evgeny 366cf94e15 Describe shared ring playback, corrected reserve history and stereo catchup 2026-10-14 00:07:52 +02:00
evgeny c0c4310f08 Clarify desktop demand reader ownership and preparation bounds 2026-10-14 00:06:23 +02:00
evgeny ef0fc85eb9 Document bounded read continuation and retained source ownership after FIN 2026-10-14 00:05:49 +02:00
evgeny 88a2b66050 Keep prior network race fixtures independent of the playback scenario clock 2026-10-14 00:04:52 +02:00
evgeny be7c3c5811 Bound desktop decoder work and drain Android codec with monotonic EOS timestamps 2026-10-14 00:04:08 +02:00
evgeny 9c01535c78 Exercise paused ring readers and graceful source close across live nodes 2026-10-14 00:02:59 +02:00
evgeny 3649e45087 Reseek on media discontinuities and bound disabled track timestamps 2026-10-14 00:01:57 +02:00
evgeny 35521fe188 Verify bounded assembly of large retained frames without new packets 2026-10-13 23:46:30 +02:00
evgeny 5937904b4a Test delayed readers without frontend queue growth and isolate codec fixtures 2026-10-13 23:41:10 +02:00
evgeny 98655284b2 Discard stale playback snapshots before reseeking a media cursor 2026-10-13 23:39:45 +02:00
evgeny 6743f84146 Verify stereo playback tempo, pitch and original media clock mapping 2026-10-13 23:35:13 +02:00
evgeny 3010fe25db Hold video only playback clocks on starvation and drain finished audio 2026-10-13 23:32:27 +02:00
evgeny a12665bbd1 Drive desktop ring playback from corrected history and physical audio time 2026-10-13 23:30:06 +02:00
evgeny e1abcb5d69 Observe actual silent device intervals when adapting playback history 2026-10-13 23:26:55 +02:00
evgeny 5c75487446 Continue bounded media assembly without waiting for new network data 2026-10-13 23:24:04 +02:00
evgeny f3bc2909e1 Initialize Android playback before handling its first media packet 2026-10-13 23:18:43 +02:00
evgeny acf374df4e Use adaptive ring backed playback and stereo tempo on Android 2026-10-13 23:16:06 +02:00
evgeny e6e276aed3 Expose shared playback timing and stereo time stretch to Android 2026-10-13 23:03:29 +02:00
evgeny 541518db81 Keep finished source data alive until delayed media readers close 2026-10-13 22:53:38 +02:00
evgeny 9781f138ed Switch Android media delivery to demand reads from the shared RS ring 2026-10-13 22:53:13 +02:00
evgeny f655f2c1d5 Keep playback audio compatible with the Android voice build 2026-10-13 22:46:02 +02:00
evgeny 8d317dbb85 Keep viewer snapshots scoped and normalize Opus packet cadence 2026-10-13 22:45:07 +02:00
evgeny 650b65078a Switch desktop media delivery to bounded demand reads from the shared ring 2026-10-13 22:42:16 +02:00
evgeny 2c7bd78a64 Track stereo time stretched audio through the device playback timeline 2026-10-13 22:37:09 +02:00
evgeny 9f37c54a3c Expose demand based audio and video reads on local stream handles 2026-10-13 22:30:47 +02:00
evgeny 866ca0923d Give audio device lead and video decode lead independent read limits 2026-10-13 22:30:47 +02:00
evgeny 75bd6f1ce1 Notify media readers when indexed playback data becomes available 2026-10-13 22:29:24 +02:00
evgeny 5c12ba253e Test independent playback readers over one authenticated stream ring 2026-10-13 22:21:29 +02:00
evgeny 485e655fd8 Separate media reader cursors from live stream receive progress 2026-10-13 22:15:00 +02:00
evgeny dc7cebaa65 Register indexed media reads and retain only two working blocks 2026-10-13 22:12:51 +02:00
evgeny 126aa9df10 Read media on demand through indexed cursors over the RS ring 2026-10-13 22:09:46 +02:00
evgeny 4ae8fc7c45 Reuse authenticated immutable RS subsets for playback reads 2026-10-13 22:04:55 +02:00
evgeny 2fac28b7e9 Build and register the shared stream playback controller test 2026-10-13 22:04:16 +02:00
evgeny 8e3ec4cb84 Test adaptive playback against a delayed audio device queue 2026-10-13 22:04:16 +02:00
evgeny b2645aed9d Add a shared playback reserve clock with corrected minute history 2026-10-13 21:56:10 +02:00
evgeny 05f2a3602a Record signed variable RS batch implementation and validation 2026-10-13 20:35:53 +02:00
evgeny 3b922ced78 Cover early BOUND in the delayed helper confirmation regression 2026-10-13 20:28:56 +02:00
evgeny 43a600c5a5 Test immediate relay forwarding and log batch authentication 2026-10-13 20:25:40 +02:00
evgeny 01d7fd5bef Document embedded batch signatures and resize pressure fixtures 2026-10-13 20:20:17 +02:00
evgeny 98d1e40bf3 Validate short media batches with an embedded source signature 2026-10-13 20:14:06 +02:00
evgeny e96b813fcb Test batch authentication after losses and recovery after rejection 2026-10-13 20:13:45 +02:00
evgeny f15c97d11a Size Android publisher buffers for the signed batch format 2026-10-13 20:09:14 +02:00
evgeny 6a5bb84d71 Centralize default stream input capacity with batch overhead 2026-10-13 20:09:14 +02:00
evgeny 0e9478d033 Account variable stream parts and continue after rejected batches 2026-10-13 20:08:07 +02:00
evgeny 47b713ea69 Publish actual part lengths and expose rejected batch status 2026-10-13 20:07:02 +02:00
evgeny cee5b26c13 Sign stream batches before RS and authenticate reconstructed data 2026-10-13 20:06:29 +02:00
evgeny 7c8470f44a Define variable stream parts with a signed RS batch envelope 2026-10-13 20:03:08 +02:00
evgeny 3477a8844c Allow RS batches to choose their block size from input length 2026-10-13 19:59:57 +02:00
evgeny 3f6cc5da52 Document callback-driven supplier discovery and verification 2026-10-13 18:16:37 +02:00
evgeny f2c5187ef1 Retry pending supplier buffers without resetting error backoff 2026-10-13 18:06:58 +02:00
evgeny da0a9ad316 Wake stream supplier discovery on Merkle and BGP callbacks 2026-10-13 17:55:19 +02:00
evgeny fec21ab5c5 Record live startup cancellation diagnosis and relay ownership 2026-10-13 17:27:41 +02:00
evgeny ccc9210232 Retain selected relay issuance before delayed READY and ACCEPT 2026-10-13 17:20:36 +02:00
evgeny 325abd8d6f Document verified 100ms stream bootstrap and aligned playback 2026-10-13 16:47:39 +02:00
evgeny 1d7f70b31c Preserve Opus preroll state across timestamp jitter and short gaps 2026-10-13 16:39:37 +02:00
evgeny eda8dfbc91 Cover paused sources and duplicate relay controls during startup 2026-10-13 16:32:53 +02:00
evgeny 8206e53b5c Warm Android Opus preroll and start audio at the first keyframe 2026-10-13 16:30:41 +02:00
evgeny 79701feef1 Drain startup audio on END and validate Opus fixture failures 2026-10-13 16:27:12 +02:00
evgeny f42b085e12 Align desktop audio startup with the first decoded video frame 2026-10-13 16:26:11 +02:00
evgeny 60aaa16327 Confirm relay readiness after reconstructing first FEC batch 2026-10-13 16:22:00 +02:00
evgeny ad20f954c5 Race initial stream suppliers with relay delay of 100ms 2026-10-13 16:14:35 +02:00
evgeny e708117259 Send relay state transitions without retry delays 2026-10-13 16:09:13 +02:00
evgeny 5def12351f Wake stream selection on validated control responses 2026-10-13 16:06:26 +02:00
evgeny 44cfebf898 Record repeated stream delivery stall during stereo verification 2026-10-13 15:30:59 +02:00
evgeny 63ccff67a2 Record stereo and rotation verification on SM and desktop 2026-10-13 15:22:56 +02:00
evgeny 50005b108f Generate continuous stereo Opus in live playback regression 2026-10-13 14:39:08 +02:00
evgeny 727106f4e9 Document stereo live audio and compact rotation controls 2026-10-13 14:30:07 +02:00
evgeny c251de4f77 Verify stereo media format and AGC channel balance 2026-10-13 14:24:59 +02:00
evgeny 8bee8c10ff Replace stream rotation menu with three marked toggle buttons 2026-10-13 14:24:59 +02:00
evgeny 214a98efb1 Play live stereo on desktop and verify channel separation 2026-10-13 14:17:26 +02:00
evgeny e06e9b0e22 Capture encode and play stereo audio in Android live streams 2026-10-13 14:15:44 +02:00
evgeny 22b62699ac Describe stereo Opus in live media blocks 2026-10-13 14:14:24 +02:00
evgeny 5f0fff5fd6 Record CAMCORDER and live radio compressor verification 2026-10-13 14:06:12 +02:00
evgeny 2a2394b34d Verify live stream compression and document shared radio AGC 2026-10-13 13:46:24 +02:00
evgeny 2e0eb89ad3 Capture CAMCORDER audio and apply radio AGC changes live 2026-10-13 13:40:08 +02:00
evgeny 6bd14c53b5 Compress stream audio before Opus using radio settings 2026-10-13 13:39:12 +02:00
evgeny 149e4d43e5 Record live desktop playback verification after queue fix 2026-10-13 13:22:51 +02:00
evgeny c72a66ba06 Record desktop shutdown remaining after core teardown 2026-10-13 13:07:51 +02:00
evgeny 736fb92ed7 Document live playback queue bounds and latency regression 2026-10-13 12:57:37 +02:00
evgeny ef67e3ed2c Preserve video frames until audio clock reaches their PTS 2026-10-13 12:55:56 +02:00
evgeny 1d984f0d0b Reproduce live video starvation behind audio output latency 2026-10-13 12:51:42 +02:00
evgeny cff92f3dac Remove obsolete debug option from configuration fixture 2026-10-13 12:18:01 +02:00
evgeny f953ab5a8f Test all debug categories and record Android settings fixes 2026-10-13 12:12:30 +02:00
evgeny 5f5d4f964a Preserve Android debug level and accept all core categories 2026-10-13 12:10:38 +02:00
evgeny 7fa7a42673 Expose native debug categories and fix Android level fields 2026-10-13 12:10:08 +02:00
evgeny df400a90aa Record partial stream recovery failure from SM and colo2 logs 2026-10-13 11:36:40 +02:00
evgeny 14e2cdc23d Document supernode stream assistance and completed validation 2026-10-13 10:18:44 +02:00
evgeny bbd13215a4 Apply router backpressure and preserve reusable relay attempts 2026-10-13 09:42:46 +02:00
evgeny e73fab0a73 Verify relay handoff expiry, replay protection and complete teardown 2026-10-13 09:38:50 +02:00
evgeny 035a2eb6d0 Retain and release media replication connection ownership 2026-10-13 09:28:51 +02:00
evgeny 57d2828496 Separate stream routing from member files and scope relay activation 2026-10-13 09:14:06 +02:00
evgeny 8dbfb4d297 Exercise supernode relay delivery and preserve ended receive handles 2026-10-13 01:28:23 +02:00
evgeny 29d91d4b19 Activate supernode stream relays on demand and release idle owners 2026-10-13 01:20:24 +02:00
evgeny 661cf032fe Define routed stream relay requests and generation-scoped replies 2026-10-13 01:15:09 +02:00
evgeny cd5e658fb9 Add internal ownership for exact-epoch stream relays 2026-10-13 01:15:09 +02:00
evgeny 8883002e3f Distinguish relay-only stream subscriptions in member profiles 2026-10-13 01:15:09 +02:00
evgeny 2cc9834e4c Use integral scores to select stream suppliers 2026-10-13 01:14:38 +02:00
evgeny 83c652a810 Merge remote-tracking branch 'origin/master' 2026-10-13 01:08:11 +02:00
evgeny 3a6dacf378 Add stream camera controls and preserve playback on changes 2026-10-13 01:00:53 +02:00
evgeny 72bcbd98e8 Handle SIGPIPE during TCP stream test teardown 2026-10-13 00:58:40 +02:00
evgeny 6a92eec983 Log stream probe backoff and pending bootstrap state 2026-10-13 00:56:18 +02:00
evgeny 3adc4a0be4 Isolate stream bootstrap teardown from shared test events 2026-10-13 00:55:12 +02:00
evgeny bf0b90d362 Exercise initial stream reinit on a single TCP link 2026-10-13 00:51:36 +02:00
evgeny 00b78fd629 Preserve pending stream requests across session reinit 2026-10-13 00:40:53 +02:00
evgeny 5ddfc582f7 Merge remote-tracking branch 'origin/master' 2026-10-12 22:38:49 +02:00
evgeny db2771e8de Fix Windows interface macro collision in NCD test 2026-10-12 22:38:23 +02:00
evgeny 29a8fb2531 Check source discovery requested before desktop startup 2026-10-12 22:31:28 +02:00
evgeny 061eb0f0f8 Preserve initial channel watches until desktop core attaches 2026-10-12 22:30:38 +02:00
evgeny 17606c66b8 Document reactive stream discovery and desktop playback ownership 2026-10-12 22:29:00 +02:00
evgeny 34349bd663 Require selected epochs and verify multiple live publishers 2026-10-12 22:28:15 +02:00
evgeny e9982a2db6 Verify live Opus output and volume with real null audio devices 2026-10-12 22:26:41 +02:00
evgeny dd034a9d42 Cover channel closure and keep stream selection usable for long lists 2026-10-12 22:21:10 +02:00
evgeny cacd377d55 Use only shared source events in Android streaming UI and tests 2026-10-12 22:20:28 +02:00
evgeny dad67360b9 Remove obsolete Android stream polling and simplify lifecycle tests 2026-10-12 22:20:28 +02:00
evgeny 6e596f34a5 Notify viewers when channels close and refresh resumed playback state 2026-10-12 22:18:04 +02:00
evgeny 4e1c36955a Test desktop stream discovery, playback, pressure and teardown 2026-10-12 22:16:31 +02:00
evgeny e5d37f6e74 Translate desktop live stream controls and playback states 2026-10-12 22:15:11 +02:00
evgeny 7addfb5aa3 Keep live decoding low latency and preserve publisher stop controls 2026-10-12 22:15:11 +02:00
evgeny b4ebaa8863 Open desktop stream playback windows from channel sources 2026-10-12 22:12:41 +02:00
evgeny fe7734b9e0 Show live sources and select a stream in desktop channel headers 2026-10-12 22:12:41 +02:00
evgeny 10f197c817 Decode and play desktop live H264 and Opus streams 2026-10-12 22:11:35 +02:00
evgeny 0a5b9b50f1 Connect desktop stream bridge to core lifecycle and events 2026-10-12 22:09:39 +02:00
evgeny d9821fa89c Add bounded desktop live media bridge and source lifecycle tests 2026-10-12 22:07:35 +02:00
evgeny e3d9ac9d31 Report Android stream close reasons and epoch changes 2026-10-12 22:01:38 +02:00
evgeny d5ed19ee34 Open Android live streams from the channel header 2026-10-12 22:01:38 +02:00
evgeny ba3dd70f6c Keep Android live sources in reactive channel state 2026-10-12 22:00:12 +02:00
evgeny ba3dfa9fcc Watch Android stream sources and validate selected epochs 2026-10-12 21:58:56 +02:00
evgeny f91894aa1b Expose verified stream sources and channel watch events 2026-10-12 21:57:20 +02:00
evgeny 90d3206071 Confirm new TCP sessions and bound reciprocal challenge retries
Negotiate new TCP sessions even when the peer epoch is known, and let the retry timer send reciprocal challenges to avoid feedback loops when confirmations are lost.

Cover peer restarts, simultaneous connects, REALITY, confirmation loss, second links, stale confirmations and deadlines. Remove forced client resets and count only validated test payloads in the UDP reconnect test.

Validation: 149 tests passed; proxy, burst and load integration tests passed; Android assembleDebug succeeded.
2026-10-12 21:29:41 +02:00
evgeny d372438b6e Reuse automatically completed profiles in the NAT fixture 2026-10-12 20:57:29 +02:00
evgeny d2b96d1340 Release cold priority after a completed partial measurement 2026-10-12 20:48:33 +02:00
evgeny a32eef9ed1 Wait for the actual DOWN timer in the owner-release test 2026-10-12 20:46:43 +02:00
evgeny c7be1ebbbe Preserve cold NAT trials in the real network fixture 2026-10-12 20:43:39 +02:00
evgeny 391059c967 Refresh signed socket metadata when changing the failure-test profile 2026-10-12 20:33:31 +02:00
evgeny bea9ca88a6 Publish the test peer profile through the instance-owned snapshot 2026-10-12 20:33:16 +02:00
evgeny 1b659335b9 Test failure recheck eligibility and coalescing on a blocked UDP peer 2026-10-12 20:33:03 +02:00
evgeny 61e3ad9d24 Start a cold measurement when automatic detection is enabled 2026-10-12 20:31:45 +02:00
evgeny 406f569989 Protect cold ingress before the third routed node is announced 2026-10-12 20:29:33 +02:00
evgeny 3294f67dbf Log cold candidate eligibility and reservation changes 2026-10-12 20:27:34 +02:00
evgeny 2dc7e8d206 Document failure recheck limits and validate requested endpoints 2026-10-12 20:26:12 +02:00
evgeny 3b894753b1 Trigger NAT rechecks after direct timeout and exhausted reverse 2026-10-12 20:25:42 +02:00
evgeny 952fbe68e2 Schedule bounded endpoint rechecks after compatible UDP failure 2026-10-12 20:25:20 +02:00
evgeny 99382cf823 Cancel UDP route probes with their contexts before socket teardown 2026-10-12 20:21:02 +02:00
evgeny ceab874abc Wait for complete NAT cycles and test an indirect private helper 2026-10-12 20:18:21 +02:00
evgeny 2354e94347 Expose pending NAT candidate cycles in local diagnostic status 2026-10-12 20:17:44 +02:00
evgeny 2ba011d3fd Document grouped control, isolated helper ports and ingress correlation 2026-10-12 20:07:49 +02:00
evgeny 179aa0ef35 Release received packets when cold NAT priority defers PONG 2026-10-12 20:05:47 +02:00
evgeny bb01f243fe Allow routed observers in the NAT integration assertions 2026-10-12 19:54:39 +02:00
evgeny 3635bcf3a9 Keep connection-manager background pings out of cold NAT trials 2026-10-12 19:44:28 +02:00
evgeny e60b03916a Test automatic detection in another group over a TCP routed helper 2026-10-12 19:30:42 +02:00
evgeny 9a24ac6bdf Try controlled ingress before asking the broker for helper mapping 2026-10-12 19:27:58 +02:00
evgeny f71e94c9d8 Trace the first UDP contacts that affect cold NAT classification 2026-10-12 19:17:06 +02:00
evgeny 8906e29102 Keep background PONG replies from contaminating cold ingress checks 2026-10-12 19:01:13 +02:00
evgeny 9bd113054c Defer reachability probes while the first NAT ingress is protected 2026-10-12 18:50:08 +02:00
evgeny 9324b8af8c Give initial NAT measurements bounded priority without opening filters 2026-10-12 18:50:08 +02:00
evgeny 585834ffbe Isolate helper traffic from the measured working sockets 2026-10-12 18:47:54 +02:00
evgeny 96fa1990b0 Keep detection attempt counters and network fixtures group-aware 2026-10-12 18:20:47 +02:00
evgeny 0ee431b490 Prefer untouched helper IPs and exercise NAT through real groups 2026-10-12 18:13:29 +02:00
evgeny 8990574c1d Complete grouped NAT control and cancel tasks with group lifetime 2026-10-12 18:08:47 +02:00
evgeny a0a4493ef2 Measure helper endpoints and protect controlled UDP ingress trials 2026-10-12 17:57:22 +02:00
evgeny 77ca1ec3dd Select NAT candidates across groups and route authenticated control 2026-10-12 17:50:45 +02:00
evgeny 2e7da4f3cc Define grouped NAT probe tags and a routed control service 2026-10-12 17:43:27 +02:00
evgeny a97589e4a6 Check desktop address rendering with compact NAT profiles 2026-10-12 17:18:23 +02:00
evgeny 53c32e5669 Document compact NAT profiles and stable measurement lifetime 2026-10-12 17:13:22 +02:00
evgeny 5429431567 Invalidate changed endpoints and verify the Android address contract 2026-10-12 17:11:56 +02:00
evgeny 6272c8a4ad Verify compact address snapshots, migration and Android JSON 2026-10-12 17:10:48 +02:00
evgeny 89f031f4f9 Keep STUN round diagnostics separate from published NAT profiles 2026-10-12 17:07:35 +02:00
evgeny ba29adf6ef Test stable published profiles across repeated NAT measurements 2026-10-12 17:06:35 +02:00
evgeny 61132a3e84 Align socket monitoring with compact address profiles 2026-10-12 17:05:23 +02:00
evgeny db8a5ee2df Retain stable NAT results and compact the address database 2026-10-12 17:04:59 +02:00
evgeny e47ae480f5 Remove time-dependent profile matching from connection setup 2026-10-12 17:01:28 +02:00
evgeny f900cda9c0 Use the last published address profile without a time limit 2026-10-12 17:01:02 +02:00
evgeny 38eaae8bb6 Remove measurement IDs and timestamps from NODEINFO profiles 2026-10-12 17:00:38 +02:00
evgeny d2e62874bb Fix Android member details layout and address formatting 2026-10-12 16:40:40 +02:00
evgeny a96d5926c7 Fix Android external network monitoring and startup readiness
Select frontend network callbacks for auto_sockets=android instead of opening a denied netlink monitor. Preserve monitor descriptor ownership, keep native monitoring failures fatal, and release caller config on failed Android core creation and restart.

Register ConnectivityManager before requesting startup, report readiness after SERVICE_STARTED, and refresh addresses after initialization with serialized updates and generation checks. Add regression coverage for denied netlink, socket failures, address updates, and fd=0 preservation. Record the separate cancellation issue for startup before readiness.

Validation: full check.sh passed, including proxy/burst/load integrations. Clean Android build installed successfully on SM-A525F and Q8; logcat confirms both cores initialized and entered the poll loop with external monitoring and post-start address refresh.
2026-10-12 16:01:26 +02:00
evgeny 72e2c89e3b Fix sockless TCP keepalive and require complete UTUN initialization
Receive keepalive through the owning ETCP link, preserve RX deadlines, and report routing metrics without TUN. Use independent netlink requests and track installed routes for rollback. Reject incomplete resource initialization and release partially constructed cores while preserving caller config ownership.

Validated startup failure and rollback, padded keepalive, standby, STCP traffic, transport lifecycle, dynamic sockets, and daemon startup. Real TUN/netlink checks passed in an isolated Linux network namespace; modified modules passed FreeBSD compilation checks.
2026-10-12 14:24:32 +02:00
evgeny bb256dccdc Extend Android playback counters across long running streams 2026-10-12 12:54:13 +02:00
evgeny a043dc9a42 Bound audio writes and release codecs after failed initialization 2026-10-12 11:49:09 +02:00
evgeny 98dcaae853 Close viewers on malformed media and release terminal owners immediately 2026-10-12 11:46:13 +02:00
evgeny eee67ac9d9 Close local preview when its publication ends 2026-10-12 11:36:07 +02:00
evgeny af580d9d90 Record Android viewer lifecycle and persisted snapshot diagnostics 2026-10-12 11:31:26 +02:00
evgeny 039c0f71f5 Pause viewers in the background and keep visible playback awake 2026-10-12 11:30:36 +02:00
evgeny 150b3c3bdb Explain invalid media metadata and codec transitions in logs 2026-10-12 11:26:27 +02:00
evgeny 1dcf6a79ce Reject overlapping core ownership of Android stream handles 2026-10-12 11:26:27 +02:00
evgeny 18661f0ef0 Constrain live preview while keeping stream controls visible 2026-10-12 11:21:30 +02:00
evgeny ef76ca5de3 Document audiovisual stream format and Android ownership contracts 2026-10-12 07:24:13 +02:00
evgeny dac5f98052 Select local preview from the verified source snapshot 2026-10-12 07:22:43 +02:00
evgeny c2c202e716 Mute local preview and clear Android media queues at detach 2026-10-12 07:22:43 +02:00
evgeny c1b1713ab1 Verify Android AVC normalization and keyframe configuration 2026-10-12 02:47:15 +02:00
evgeny e8adf03826 Preserve stream control events when discarding delayed media 2026-10-12 02:42:01 +02:00
evgeny 1209d8e4b7 Keep video clock moving through audio underruns and drain final playback 2026-10-12 02:30:36 +02:00
evgeny e09ee919a5 Release capture before service ownership and report startup failures 2026-10-12 02:29:26 +02:00
evgeny c9743ee85d Exercise Android stream queues and teardown against a live core 2026-10-12 02:29:08 +02:00
evgeny 0c613eacbc Show verified source snapshots without borrowing core pointers 2026-10-12 02:28:02 +02:00
evgeny 6c692399c2 Build verified live source snapshots in the core thread 2026-10-12 02:27:44 +02:00
evgeny 4fc1f31651 Prevent competing Android capture while broadcasting 2026-10-12 02:07:04 +02:00
evgeny d4ca812578 Open live streams from Android channel navigation 2026-10-12 02:07:04 +02:00
evgeny 8502d6f2d7 Add localized Android stream controls and player screen 2026-10-12 02:06:27 +02:00
evgeny ee851b4aa6 Play live streams with bounded queues and audio clock synchronization 2026-10-12 02:04:38 +02:00
evgeny f2a5dde761 Declare stream camera permissions and cancel capture at core restart 2026-10-12 02:02:48 +02:00
evgeny e4f2e647d7 Own live camera sessions in an Android foreground service 2026-10-12 02:02:48 +02:00
evgeny c50d5066a9 Capture Android AVC and Opus on a shared monotonic timeline 2026-10-12 02:01:09 +02:00
evgeny 2f707366f3 Expose session scoped Android stream operations 2026-10-12 01:51:10 +02:00
evgeny 6f544b4ca2 Add Android JNI transport and independent stream Opus codecs 2026-10-12 01:51:10 +02:00
evgeny 0ee1163a0b Bind Android media queues to core lifetime and source epochs 2026-10-12 01:50:07 +02:00
evgeny 938289a6f0 Include Android streaming bridge and refine malformed wire tests 2026-10-12 01:49:40 +02:00
evgeny 36fceec6b2 Bridge Android live streams through bounded session queues 2026-10-12 01:49:07 +02:00
evgeny fc3518f5ba Test media boundaries FEC losses and keyframe recovery 2026-10-12 01:46:06 +02:00
evgeny 5c23c10c04 Register audiovisual stream sources and regression target 2026-10-12 01:46:06 +02:00
evgeny 1389bac261 Define FEC protected audiovisual blocks and frame assembly 2026-10-12 01:45:08 +02:00
evgeny 47caca82a1 Expose atomic publication of stream batches 2026-10-12 01:43:31 +02:00
evgeny baeaef3ab1 Preserve logical block boundaries in stream sources 2026-10-12 01:43:21 +02:00
evgeny 4f9fefe9e5 Test and document NCD ownership protecting CM direct probes beyond down timeout 2026-10-12 01:34:44 +02:00
evgeny fdaa20977d Recheck expired down lifetime when the last NCD owner releases it 2026-10-12 01:34:44 +02:00
evgeny 11f1a14063 Retain down ETCP connections while local NCD handles exist 2026-10-12 01:34:44 +02:00
evgeny 0d7f7630b0 Expose actual NCD handle ownership for an ETCP transport 2026-10-12 01:34:44 +02:00
evgeny 6704a18897 Clarify independent RX watchdog and sleep-aware graceful close deadlines 2026-10-12 01:34:44 +02:00
evgeny 24c64967fd Propagate remote UDP link DOWN to the connection expiry timer 2026-10-12 01:34:44 +02:00
evgeny 85b4af5b1d Shorten RX deadline immediately when a sleeping peer wakes 2026-10-12 01:34:44 +02:00
evgeny 2e66cdb122 Preserve cancellation of pending outgoing attempts and size packet fixture correctly 2026-10-12 01:34:44 +02:00
evgeny b57221f6b5 Document ETCP down retention and separate RX lifetime from keepalive sending 2026-10-12 01:34:44 +02:00
evgeny 1c53ef597d Register lifecycle regressions and cancel timers owned by synthetic fixtures 2026-10-12 01:34:44 +02:00
evgeny 0ba8380db4 Test incoming ETCP expiry, reconnect, sleep and graceful close 2026-10-12 01:34:44 +02:00
evgeny f090d697c4 Initialize inbound graceful close and honor remote transport ownership 2026-10-12 01:34:44 +02:00
evgeny 3cfdb9e6ec Keep a finite RX deadline while ETCP keepalive sending is suspended 2026-10-12 01:34:44 +02:00
evgeny 034be69ac1 Expire ETCP transports after 30 seconds continuously down 2026-10-12 01:34:44 +02:00
evgeny b852058501 Record validated STUN fallback, sanitizer checks and IPv6 follow-up 2026-10-12 01:31:29 +02:00
evgeny b3830e0264 Document signed profile source and reproducible isolated STUN bench 2026-10-12 01:28:49 +02:00
evgeny c19f835334 Document implemented interface STUN fallback and provenance semantics 2026-10-12 01:27:40 +02:00
evgeny 9f907d0f31 Stop NAT detectors before service callbacks and verify STUN restart isolation 2026-10-12 01:25:59 +02:00
evgeny 152ebfef48 Release retained STUN port history during final core destruction 2026-10-12 01:24:00 +02:00
evgeny 3d5f009380 Keep STUN port history owned by the core across configuration reloads 2026-10-12 01:24:00 +02:00
evgeny 3735b78328 Verify STUN cache expiry and preserve partial ETCP measurement priority 2026-10-12 01:20:56 +02:00
evgeny 709b0a3271 Wait for the real observer link and distribute STUN bench scripts 2026-10-12 01:15:31 +02:00
evgeny 8c5e4ab691 Exercise STUN fallback and ETCP promotion with real namespace NAT 2026-10-12 01:14:09 +02:00
evgeny a581cb2086 Add isolated STUN fallback scenario and equivalent NAT for test ports 2026-10-12 01:12:28 +02:00
evgeny f433413c49 Test deduplicated STUN groups and fallback promotion through real ETCP 2026-10-12 01:01:11 +02:00
evgeny 164a3a1f0f Keep connection attempts available for STUN hints and verify signed provenance 2026-10-12 00:58:50 +02:00
evgeny 9aa56e6b56 Show NAT profile origin and recheck interface STUN from control 2026-10-12 00:58:50 +02:00
evgeny 76d2e58f19 Expose ETCP and STUN profile provenance in monitor protocol 2026-10-12 00:58:32 +02:00
evgeny 01b0992c39 Select interface STUN fallback only when ETCP lacks independent observers 2026-10-12 00:57:54 +02:00
evgeny 735ac36579 Sign endpoint profile provenance and restrict external-address publication 2026-10-12 00:56:43 +02:00
evgeny 6beae21ec4 Group STUN probes by interface path and refresh independent-port results 2026-10-12 00:55:29 +02:00
evgeny 8b8b73983b Plan interface STUN profiles as fallback for unavailable ETCP probes 2026-10-12 00:42:14 +02:00
evgeny 37e897d0d2 Plan unified STUN and ETCP endpoint measurements 2026-10-12 00:09:13 +02:00
evgeny 5c83aac96e Adapt STUN diagnostics to endpoint profiles and helper sockets 2026-10-12 00:03:07 +02:00
evgeny 39dd038831 Record ASAN validation of endpoint detector lifecycle 2026-10-12 00:01:40 +02:00
evgeny ff69552a61 Measure owned endpoint mapping and inbound reachability separately 2026-10-12 00:01:40 +02:00
evgeny b54307a0df Ignore local hardware directory 2026-10-12 00:01:40 +02:00
evgeny 65f05c86ed Save workspace state before address detection redesign 2026-10-12 00:01:40 +02:00
evgeny 5eb1c86acf Include stream bench validation notes in source distribution 2026-10-12 00:01:40 +02:00
evgeny b8f8818eef Record validated stream bench runs and explicit RPC error diagnostics 2026-10-12 00:01:40 +02:00
evgeny 89c6482a96 Record clean NAT startup and monotonic restart contract in stream specification 2026-10-12 00:01:40 +02:00
evgeny d44b4bc682 Test repeated restart before deferred GAP and prohibit replay under overload 2026-10-12 00:01:40 +02:00
evgeny 802134c846 Preserve delivered cursor when stream restarts from a stale supplier 2026-10-12 00:01:40 +02:00
evgeny 1969ca5535 Require monotonic consumer cursor across stream receive restart 2026-10-12 00:01:40 +02:00
evgeny 5084670820 Recreate bench network after calibration to clear NAT and conntrack state 2026-10-12 00:01:40 +02:00
evgeny e78eaf45f7 Document namespace stream bench and completion after consumer drain 2026-10-12 00:01:40 +02:00
evgeny a877ba8a73 Keep automatic stream recovery active until signed END is drained 2026-10-12 00:01:40 +02:00
evgeny a4e899807c Clear closed fixture handles before terminal stream regression 2026-10-12 00:01:40 +02:00
evgeny d99b0e5525 Reproduce automatic stream stall after early END with incomplete FEC batch 2026-10-12 00:01:40 +02:00
evgeny 46ac9a03b9 Add forced TCP bench mode and verify observed source timestamp wraps 2026-10-12 00:01:40 +02:00
evgeny 57bf4e490d Bound namespace startup and measure LAN quality before stream tests 2026-10-12 00:01:40 +02:00
evgeny 649be77fa3 Use core clock for stream metrics and require new data after WAN recovery 2026-10-12 00:01:40 +02:00
evgeny 5c1bb06294 Expose source clock and stream metrics in bench snapshots 2026-10-12 00:01:40 +02:00
evgeny 284b603e6e Account initial GAP independently of first delivered stream record 2026-10-12 00:01:40 +02:00
evgeny e92e08e5cc Document stream lab and test namespace isolation guards 2026-10-12 00:01:40 +02:00
evgeny 3dc682087a Wait for verified Merkle profiles as well as BGP reachability 2026-10-12 00:01:40 +02:00
evgeny ebe3232268 Apply optional load collection only to peer queue telemetry 2026-10-12 00:01:40 +02:00
evgeny 0eae531706 Include local BGP presence and make queue diagnostics opt-in 2026-10-12 00:01:40 +02:00
evgeny e9e93ef26b Wire live stream scenarios into isolated bench launcher 2026-10-12 00:01:40 +02:00
evgeny fe4791d6f5 Add sixteen-node live JOIN and streaming scenarios 2026-10-12 00:01:39 +02:00
evgeny 6332e75e61 Add real uTun stream bench node with payload and latency validation 2026-10-12 00:01:39 +02:00
evgeny 856fbc61b1 Keep NAT probes independent of cached conntrack and DHCP timers 2026-10-12 00:01:39 +02:00
evgeny 47948fe847 Add rootless isolated stream bench launcher 2026-10-12 00:01:39 +02:00
evgeny 0b1a081e34 Implement isolated stream bench networking and NAT calibration 2026-10-12 00:01:39 +02:00
evgeny 0172aa3081 Create dedicated stream network-namespace bench topology 2026-10-12 00:01:39 +02:00
evgeny 4096691eb2 Record full-suite and final sanitizer verification for automatic streaming 2026-10-12 00:01:39 +02:00
evgeny fc63b801f9 Clarify generation discovery on every stream INFO probe 2026-10-12 00:01:39 +02:00
evgeny af1f3cc007 Document nonce-bound unilateral stream generation recovery 2026-10-12 00:01:39 +02:00
evgeny 6b18ad45ea Restore automatic suppliers after proven resynchronization and test unilateral generation changes 2026-10-12 00:01:39 +02:00
evgeny a8cd802aad Resynchronize unilateral peer generations through nonce-bound INFO without epoch ping-pong 2026-10-12 00:01:39 +02:00
evgeny 9a648219cf Document automatic stream selection, wire v3, active-mode ownership and verified behavior 2026-10-12 00:01:39 +02:00
evgeny 6749d09025 Enforce distinct manual and automatic upstream ownership 2026-10-12 00:01:39 +02:00
evgeny 0d2d7c913d Keep optimizer diagnostic format strings within repository line limits 2026-10-12 00:01:39 +02:00
evgeny 090964a786 Log provider offers and measured reasons for confirmed stream migrations 2026-10-12 00:01:39 +02:00
evgeny fcbdbd6002 Test probe burst, second-level admission and complete-cycle timing boundaries 2026-10-12 00:01:39 +02:00
evgeny c6bf960eec Isolate monotonic probe scheduling policy for precise boundary checks 2026-10-12 00:01:39 +02:00
evgeny ab4b75986d Reopen closed peer ownership and drive reverse requests from current stream attempts 2026-10-12 00:01:39 +02:00
evgeny 7144bbe694 Verify deferred standby restoration and END-only automatic streams 2026-10-12 00:01:39 +02:00
evgeny 03814b9660 Tie active-mode holds to stream ownership and deliver signed END for empty live sources 2026-10-12 00:01:39 +02:00
evgeny bccf8c6b38 Preserve frontend activity requests while stream owners hold the core active 2026-10-12 00:01:39 +02:00
evgeny 1308e8201e Verify direct, reverse-only and incompatible NCD capability checks without side effects 2026-10-12 00:01:39 +02:00
evgeny aa3fb9cac7 Admit reverse-capable providers without requiring an outgoing-compatible address 2026-10-12 00:01:39 +02:00
evgeny 22342b310c Bound stale offer storage, detect initial DATA stalls and report verified FEC protection 2026-10-12 00:01:39 +02:00
evgeny 2d9616eca5 Refresh matching active path RTT through probes and isolate integration event counters 2026-10-12 00:01:39 +02:00
evgeny 7db3008e5c Wait for the actual automatic stream source in Merkle subscription checks 2026-10-12 00:01:39 +02:00
evgeny 31d0db939a Include NCD compatibility API in automatic stream integration test 2026-10-12 00:01:39 +02:00
evgeny bc49b452f9 Exercise automatic stream selection, INFO-only probes and verified overlap failover 2026-10-12 00:01:39 +02:00
evgeny 99359f987c Use observed provider quality and keep empty-source queue accounting bounded 2026-10-12 00:01:39 +02:00
evgeny cb9ef94501 Keep protocol and overload fixtures under explicit manual upstream control 2026-10-12 00:01:39 +02:00
evgeny 94c482ed35 Handle empty sources and next-batch tail subscriptions without startup races 2026-10-12 00:01:39 +02:00
evgeny ef48fa2a37 Enable automatic upstream selection for subscriptions with lifecycle-safe cleanup 2026-10-12 00:01:39 +02:00
evgeny 576c79657b Implement stream supplier probe cycles, FEC-aware selection and overlap migration 2026-10-12 00:01:39 +02:00
evgeny 3db2130b56 Define per-stream automatic selection settings and diagnostic manual mode 2026-10-12 00:01:39 +02:00
evgeny 0b9b395879 Keep SUBSCRIBE deadlines and prevent ambiguous pending INFO correlation 2026-10-12 00:01:39 +02:00
evgeny 35ad47c653 Implement DATA-free stream probes with ranges, paths and load offers 2026-10-12 00:01:39 +02:00
evgeny 984153b90a Expose monotonic age of verified substream progress 2026-10-12 00:01:39 +02:00
evgeny 9cd285ddb0 Define INFO-only stream probes and provider offer snapshots 2026-10-12 00:01:39 +02:00
evgeny ca5a374042 Expose side-effect-free NCD transport compatibility using shared link matching 2026-10-12 00:01:39 +02:00
evgeny ee8baae160 Record full and sanitizer checks for stream overload delivery 2026-10-12 00:01:39 +02:00
evgeny f10078e482 Document timestamp metrics and negotiated stream overload cuts 2026-10-12 00:01:39 +02:00
evgeny 0282fe7e17 Keep newer INFO probes alive when old queued probes expire 2026-10-12 00:01:39 +02:00
evgeny 4142c7691a Expire stale stream control without retaining orphan issuances 2026-10-12 00:01:39 +02:00
evgeny 223bb145e6 Compare overload request history when checking CPU-only load 2026-10-12 00:01:39 +02:00
evgeny c9ce8d3a74 Expose overload admission recovery and wait for it in tests 2026-10-12 00:01:39 +02:00
evgeny bee7bdaa70 Expose stream load and network APIs with C linkage 2026-10-12 00:01:39 +02:00
evgeny 695741d9d3 Exclude stale growth and pending cuts from global overload budgets 2026-10-12 00:01:39 +02:00
evgeny 01324d2ebb Avoid an extra FEC cut for a marginal overload safety reserve 2026-10-12 00:01:39 +02:00
evgeny 3d6c843958 Verify global stream pressure requires backlog as well as CPU 2026-10-12 00:01:39 +02:00
evgeny 97495377b2 Assert rate-based parity cuts rather than a fixed close count 2026-10-12 00:01:39 +02:00
evgeny 1174d71a06 Wait for CLOSED delivery after unblocking overload control 2026-10-12 00:01:39 +02:00
evgeny 108e97b550 Validate partial overload cuts preserve six FEC data streams 2026-10-12 00:01:39 +02:00
evgeny a4e080da91 Prefer FEC parity cuts and refresh receive progress on inspection 2026-10-12 00:01:39 +02:00
evgeny f11592be3e Exercise stream overload under real ETCP backpressure 2026-10-12 00:01:39 +02:00
evgeny 61df1204f8 Expect expired arrival intervals to leave the load window 2026-10-12 00:01:39 +02:00
evgeny df474a33d0 Check stream pressure timing, accounting and wide metric fields 2026-10-12 00:01:39 +02:00
evgeny c10e0c7e3c Negotiate frozen-rate stream cuts with bounded overload grace 2026-10-12 00:01:39 +02:00
evgeny a07c53a397 Measure stream issuances, probe RTT and pending data demand 2026-10-12 00:01:39 +02:00
evgeny 921340ae60 Track signed timestamp progress in each local stream subflow 2026-10-12 00:01:39 +02:00
evgeny fabd7ac91f Define stream pressure negotiation and timestamp metric snapshots 2026-10-12 00:01:39 +02:00
evgeny fec1916a58 Observe stream cache arrivals and exact pending block age 2026-10-12 00:01:39 +02:00
evgeny e90ad5acbd Account stream demand and confirm sustained queue pressure 2026-10-12 00:01:39 +02:00
evgeny ddc386d16c Record ASAN and full checks for live NCD stream delivery 2026-10-12 00:01:39 +02:00
evgeny 007f5d21b2 Document live NCD stream delivery, wire format and limits 2026-10-12 00:01:39 +02:00
evgeny 67152f6b7b Verify independent stream groups share one direct ETCP session 2026-10-12 00:01:39 +02:00
evgeny ee36c578e2 Reject premature stream completion and failed ACCEPT enqueue 2026-10-12 00:01:39 +02:00
evgeny 0b202bb3e7 Bound stream path allocations and validate wire rejection cases 2026-10-12 00:01:39 +02:00
evgeny fc80186043 Restart stream receives and expose confirmed delivery gaps 2026-10-12 00:01:39 +02:00
evgeny d6f935d779 Locate recoverable stream batches when skipping delivery gaps 2026-10-12 00:01:39 +02:00
evgeny 109936f846 Revalidate stream peers and respect asynchronous ETCP reset 2026-10-12 00:01:39 +02:00
evgeny 09e86a16f6 Exercise live stream relay, common start, leases and epochs 2026-10-12 00:01:39 +02:00
evgeny d83e85b8ca Report stream ring bounds and handle expired and final cursors 2026-10-12 00:01:39 +02:00
evgeny c2179b3959 Implement NCD stream issuances, ring cursors and routed reverse 2026-10-12 00:01:39 +02:00
evgeny 36c4ff6050 Connect local stream lifetime and signed END to network delivery 2026-10-12 00:01:39 +02:00
evgeny b31aa9f71d Retain stream block paths and locate gaps in ring delivery 2026-10-12 00:01:39 +02:00
evgeny 18fe51ad25 Define direct stream messages, paths and signed completion 2026-10-12 00:01:39 +02:00
evgeny 12c0de503d Document installer builds and register packaging checks 2026-10-12 00:01:39 +02:00
evgeny 804007c997 Test Windows installer contents and build error propagation 2026-10-12 00:01:39 +02:00
evgeny 6d3c555ac4 Record successful full stream integration checks 2026-10-12 00:01:39 +02:00
evgeny fa79b7d30c Document stream CHAT integration and signed member option format 2026-10-12 00:01:39 +02:00
evgeny 5f9cb86ff0 Package only imported DLLs and log firewall command output 2026-10-12 00:01:39 +02:00
evgeny a62540800b Cancel local streams when signed membership is invalidated 2026-10-12 00:01:39 +02:00
evgeny c250e703f7 Create VibeChat installer from Windows BAT entry points 2026-10-12 00:01:39 +02:00
evgeny 197696075c Release owned BGP path entries before removing their queues 2026-10-12 00:01:39 +02:00
evgeny 78e0312fee Validate stream lifecycle and Merkle BGP integration 2026-10-12 00:01:39 +02:00
evgeny 1b406202b5 Integrate installer generation into Windows build scripts 2026-10-12 00:01:39 +02:00
evgeny 2e70c3baed Add VibeChat Windows installer and runtime packaging 2026-10-12 00:01:39 +02:00
evgeny 30106c8f93 Attach stream subscriptions to CHAT lifecycle and member profiles 2026-10-12 00:01:39 +02:00
evgeny b14f00a4b2 Check Windows ChatGUI config writability directly 2026-10-12 00:01:38 +02:00
evgeny 753aa4217d Use LocalAppData fallback for Windows ChatGUI storage 2026-10-12 00:01:38 +02:00
evgeny b6f80668d1 Define signed stream member options and BGP eligibility 2026-10-12 00:01:38 +02:00
evgeny a33666b778 Add atomic updates for signed member profile options 2026-10-12 00:01:38 +02:00
evgeny ec82d95a03 Add signed FEC stream core and source buffering 2026-10-12 00:01:38 +02:00
evgeny 2c5deafe56 Add independent STUN NAT probes with RFC 5780 discovery 2026-10-11 23:35:47 +02:00
evgeny 9cc996b775 Document Reed-Solomon module and update streaming design 2026-10-10 19:45:14 +02:00
evgeny 2967d2fb71 Fix matrix inverse syntax and make bounded conversions explicit 2026-10-10 19:38:08 +02:00
evgeny d9d4a7807f Test Reed-Solomon recovery and integrate codec into builds 2026-10-10 19:37:07 +02:00
evgeny 831018f161 Add batch Reed-Solomon codec with caller-owned buffers 2026-10-10 19:35:10 +02:00
evgeny 84a171dcac tests: keep build script regressions outside the regular check 2026-10-10 17:48:20 +02:00
evgeny 8de64174bb tests: remove unnecessary barriers from parallel checks 2026-10-10 17:42:31 +02:00
evgeny 69a99c7860 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	tests/Makefile.am
2026-10-10 17:25:40 +02:00
evgeny c85a8116ef tests: run checks in parallel with available CPU count by default 2026-10-10 17:14:29 +02:00
evgeny b16da44e42 tests: assign STCP ping and REALITY fallback ports at bind 2026-10-10 16:54:56 +02:00
evgeny 7ae2f74643 tests: discover live endpoints in forked JOIN and network polls 2026-10-10 16:51:38 +02:00
evgeny 482d2787fb tests: retain automatically assigned endpoints across restart 2026-10-10 16:48:19 +02:00
evgeny 12d4e2433e dummynet: route between explicit independently bound endpoints 2026-10-10 16:46:19 +02:00
evgeny 70b55e4626 tests: assign CM phase listeners and failure endpoints dynamically 2026-10-10 16:40:56 +02:00
evgeny e836090a02 tests: allocate live and blackhole multilink endpoints dynamically 2026-10-10 16:39:17 +02:00
evgeny 4b499a076a tests: derive NCD fixture addresses from bound sockets 2026-10-10 16:37:36 +02:00
evgeny b0ca182fc5 tests: preserve diagnostic filters when wiring peer endpoints 2026-10-10 16:35:07 +02:00
evgeny 45a6320b5e tests: assign JOIN, member files and DM endpoints dynamically 2026-10-10 16:31:54 +02:00
evgeny e4fe534382 tests: isolate media delivery endpoints and scratch files 2026-10-10 16:23:09 +02:00
evgeny 336b6871f3 tests: allocate broadcast, avatar and invite listeners dynamically 2026-10-10 16:14:53 +02:00
evgeny e25d5cc220 tests: use bound endpoints for CM and database synchronization 2026-10-10 16:11:00 +02:00
evgeny 101266d1a7 tests: assign independent CM and chat sync listener ports 2026-10-10 16:07:43 +02:00
evgeny efdfb1d835 tests: inherit the ready echo listener on an automatic port 2026-10-10 16:06:07 +02:00
evgeny 4e2cc0e35a tests: hold OS-assigned HTTP and SOCKS listener ports 2026-10-10 16:04:19 +02:00
evgeny 08865b2909 tests: allocate UDP proxy and NAT transport ports automatically 2026-10-10 15:56:28 +02:00
evgeny 0af9a3092b tests: allocate ports independently in every STCP scenario 2026-10-10 15:55:28 +02:00
evgeny dc0dbbf720 headless: expose OS-assigned control and audio listener ports 2026-10-10 15:51:04 +02:00
evgeny 91909fbb1e tests: use independent ports for radio and call topologies 2026-10-10 15:45:38 +02:00
evgeny ce8144b79e tests: assign independent ports to BGP topology listeners 2026-10-10 15:44:00 +02:00
evgeny 0c09252dd6 tests: assign Merkle and DM media fixture ports dynamically 2026-10-10 15:40:34 +02:00
evgeny 98529b3268 tests: allocate STCP traffic and link listener ports automatically 2026-10-10 15:32:47 +02:00
evgeny 0dcecdd7b2 tests: remove PID ports and allocate SOCKS listeners dynamically 2026-10-10 15:30:48 +02:00
evgeny 44522027e7 tests: use ephemeral ports for ETCP traffic fixtures 2026-10-10 15:29:46 +02:00
evgeny 3f4a67f552 tests: assign NAT and route ping ports through bind zero 2026-10-10 15:28:48 +02:00
evgeny 4afd5df55f tests: use bound ephemeral ports for ETCP and IPv6 peers 2026-10-10 15:27:47 +02:00
evgeny 991fc0a2c1 transport: publish ports assigned by the operating system 2026-10-10 15:26:08 +02:00
evgeny 4908cb7e19 Document shared FreeBSD builds and locate Bash through PATH 2026-10-10 15:25:58 +02:00
evgeny c16334d551 Run build regressions with native FreeBSD tools and Windows binaries 2026-10-10 15:25:58 +02:00
evgeny e0ba199e20 Share incremental builds on FreeBSD and select portable hardening flags 2026-10-10 15:25:58 +02:00
evgeny d6c6a4d111 Use verified incremental builds instead of mandatory clean 2026-10-10 15:25:58 +02:00
evgeny 62a853e73c Detect compiler path changes and verify safe configuration cleanup 2026-10-10 15:25:58 +02:00
evgeny ff2eae2efb Verify build mode transitions and propagate GUI job counts 2026-10-10 15:25:58 +02:00
evgeny ff9d205d5b Track build configuration and preserve incremental header dependencies 2026-10-10 15:25:58 +02:00
evgeny 6437665a53 tests: accelerate session, recovery and SOCKS retry timers 2026-10-10 15:11:26 +02:00
evgeny aec9536522 tests: await proxy server readiness and retain worker failures 2026-10-10 15:10:09 +02:00
evgeny f843b553c7 tests: accelerate proxy regression event waits 2026-10-10 15:08:47 +02:00
evgeny d9c8e006b5 tests: accelerate standby phases and group connection retries 2026-10-10 15:06:56 +02:00
evgeny 361c7df812 tests: accelerate radio timers and run it among short checks 2026-10-10 14:55:53 +02:00
evgeny a1fdca09f6 tests: accelerate Merkle setup and drain waits 2026-10-10 14:54:39 +02:00
evgeny 7506da41f0 tests: keep Merkle stress records changing and verify final versions 2026-10-10 14:53:37 +02:00
evgeny 17777c540b tests: finish CPU load phases after a complete real window 2026-10-10 14:51:59 +02:00
evgeny 91081fc5c7 tests: accelerate autosocket waits and payload verification 2026-10-10 14:49:42 +02:00
evgeny 3eee716b50 tests: run short checks before slow and load scenarios 2026-10-10 14:22:06 +02:00
evgeny 0448a84286 tests: replace slow disk sleep with six-second clock-driven gate 2026-10-10 14:19:27 +02:00
evgeny 3baaa42c82 tests: accelerate BGP waits and require single-link DOWN and UP 2026-10-10 14:17:21 +02:00
evgeny 39594ad800 tests: accelerate DM retries and TTL with synchronized clocks 2026-10-10 14:14:03 +02:00
evgeny 414d40c00c tests: accelerate JOIN waits and verify timeout boundaries 2026-10-10 13:55:04 +02:00
evgeny cb32aa5aac tests: accelerate connection manager phase and recovery waits 2026-10-10 13:52:27 +02:00
evgeny 069ecc900a tests: accelerate router fault timers with real I/O clock driver 2026-10-10 13:46:50 +02:00
evgeny ec66a7e4f5 tests: detect avatar BUSY ACK repeats with ACK counter 2026-10-10 13:29:47 +02:00
evgeny 2a9a92cc34 tests: finish wrong-key STCP case when handshake closes 2026-10-10 13:27:27 +02:00
evgeny 9b879d6ced tests: wait for avatar backpressure and shorten NCD timeout fixture 2026-10-10 13:25:46 +02:00
evgeny 5805edc3dc tests: shorten mock NTP and DNS shutdown waits 2026-10-10 13:25:04 +02:00
evgeny 3f9edc88c4 Make privilege, port and fd handling reliable in tests 2026-10-10 13:09:45 +02:00
evgeny 5a9e61164b Measure uasync CPU load and display it in desktop and Android GUIs
Sample thread CPU usage without waking idle loops, expose a one-second moving average, and refresh compact GUI indicators at 3 Hz while visible on Android. Add load and bridge regression coverage, streaming notes, and task list cleanup.
2026-10-10 12:31:13 +02:00
evgeny 8bd6e4fb2d Remove obsolete trailing space after channel moc cleanup 2026-10-10 11:18:59 +02:00
evgeny e8a4b8dd4e Translate the group header menu labels 2026-10-10 11:18:34 +02:00
evgeny 61f2ca7a88 Remove group row icons and give titles the freed space 2026-10-10 11:18:17 +02:00
evgeny bfdd9cde15 Remove inline action hit targets from channel rows 2026-10-10 11:17:32 +02:00
evgeny b14bfa95c2 Collect group actions in the conversation header menu 2026-10-10 11:17:00 +02:00
evgeny 42efbbc7da Remove the file manager button from the channel footer 2026-10-10 11:07:02 +02:00
evgeny 8f908c320a Open own group files from the conversation header 2026-10-10 11:06:45 +02:00
evgeny 5ed813fe06 Record recursive removal checks and the receipt cache limit 2026-10-10 11:03:44 +02:00
evgeny 7eefb499f3 Cover recursive confirmation and storage receipt exhaustion 2026-10-10 11:02:31 +02:00
evgeny b4a9339459 Test recursive removal against real disk storage 2026-10-10 10:59:58 +02:00
evgeny afc54eae00 Confirm recursive deletion and localize removal progress 2026-10-10 10:58:45 +02:00
evgeny 7244f22722 Remove directory trees after a complete preflight scan 2026-10-10 10:58:25 +02:00
evgeny 973c734226 Defer closing until batch cancellation and cleanup finish 2026-10-10 09:38:35 +02:00
evgeny 4a6765c49a Wait for the file manager to finish copying every entry 2026-10-10 09:37:44 +02:00
evgeny db91bccda3 Keep deferred drag results owned by their operation 2026-10-10 01:58:13 +02:00
evgeny 11fc932905 Restore keyboard focus and test changed-tree cleanup 2026-10-10 01:57:28 +02:00
evgeny f7ff2df9a7 Place the native drag fixture beside the file manager 2026-10-10 01:43:06 +02:00
evgeny 3a6d075cbb Add an opt-in native file manager drag integration test 2026-10-10 01:42:42 +02:00
evgeny f0e68edad1 Translate batch file and directory operations 2026-10-10 01:41:42 +02:00
evgeny 1ed467d236 Validate batch snapshots and freeze deletion confirmation context 2026-10-10 01:41:42 +02:00
evgeny 8785fc358a Test range selection and recursive file tree transfers 2026-10-10 01:40:39 +02:00
evgeny 400b9fa93c Adapt browser regressions to asynchronous batch completion 2026-10-10 01:39:43 +02:00
evgeny 2e9babe73b Build batch transfers and wait for cancellation on close 2026-10-10 01:38:54 +02:00
evgeny 7bfa75b32c Connect multi-selection and folder transfers to the browser 2026-10-10 01:38:28 +02:00
evgeny 884eb4b412 Add cancellable file tree batch operations 2026-10-10 01:37:14 +02:00
evgeny ac17ffda54 Honor the expected file version before downloading 2026-10-10 01:35:28 +02:00
evgeny 468aeeebc7 Test Android file wire formats and nonempty directory status 2026-10-10 01:27:34 +02:00
evgeny 11b6f78924 Share exported files safely and show background transfer progress 2026-10-10 01:27:34 +02:00
evgeny a630401d10 Localize file operations and refine transfer notifications 2026-10-10 01:27:17 +02:00
evgeny 4abfbc3e9c Open Android file browser from channels and members 2026-10-10 01:27:17 +02:00
evgeny 6a3def3c9a Add a mobile member file browser with safe file actions 2026-10-10 01:27:17 +02:00
evgeny e97885eb22 Expose member file commands through Android JNI 2026-10-10 01:15:32 +02:00
evgeny 51e7f821e9 Own Android file transfers and core activity independently of UI 2026-10-10 01:15:32 +02:00
evgeny 6e5f86b2b5 Share Android file codecs and request IDs with avatars 2026-10-10 01:11:55 +02:00
evgeny e0a287d797 Report nonempty member file directories precisely 2026-10-10 01:11:54 +02:00
evgeny 39946e3cd9 Reactivate offscreen browser after confirmation dialogs 2026-10-10 00:45:49 +02:00
evgeny eb9d379efc Wait for modal focus restoration in file shortcut test 2026-10-10 00:44:42 +02:00
evgeny 93a6277ca4 Keep file navigation focused and open entries with Enter 2026-10-10 00:41:18 +02:00
evgeny 043257cabf Add Delete and Backspace shortcuts to group files 2026-10-10 00:40:25 +02:00
evgeny 6d8c28f228 Verify delayed file MIME across success failure and cancellation 2026-10-10 00:22:22 +02:00
evgeny c61a6da884 Translate file manager export actions and status 2026-10-10 00:20:28 +02:00
evgeny 9640a18b03 Test file manager copy and deferred drag completion 2026-10-10 00:20:27 +02:00
evgeny 4049a3f884 Deliver remote file drags in one gesture using deferred MIME 2026-10-10 00:19:08 +02:00
evgeny e8ca27b590 Export group files through the clipboard and native file drags 2026-10-10 00:16:46 +02:00
evgeny 7d6b45ba5d Accept file drops inside the Group files window 2026-10-10 00:13:33 +02:00
evgeny 04e8a18c9a Translate file drop and upload queue messages 2026-10-09 23:32:47 +02:00
evgeny 17f5c0ecbd Cover footer file drops and upload queue lifecycle 2026-10-09 23:32:29 +02:00
evgeny d4cef49f88 Validate dropped file sources outside the GUI thread 2026-10-09 23:31:27 +02:00
evgeny 49ee66d49c Accept file drops across the channel footer 2026-10-09 23:30:33 +02:00
evgeny b631c4ed72 Add sequential member file uploads with destination locking 2026-10-09 23:29:56 +02:00
evgeny 91a3a621d0 Translate the own files button tooltip 2026-10-09 22:58:05 +02:00
evgeny 2e4ed0347b Add own files button to the channel list footer 2026-10-09 22:58:01 +02:00
evgeny 7f3247bfcc radio: add activation controls, live VAD meters and signal diagnostics 2026-10-09 16:11:11 +02:00
evgeny fddbba217d android: add level-triggered radio and inline activation settings 2026-10-09 00:06:55 +02:00
evgeny 44af542f61 chatgui: add radio activation by signal level with hysteresis 2026-10-08 17:53:16 +02:00
evgeny 2845270016 Add diagnostics for stalled PTT shortcut recording 2026-10-08 15:00:25 +02:00
evgeny d149bad5fc radio: keep drain diagnostics at burst boundaries and test queued PCM 2026-10-08 14:33:09 +02:00
evgeny f054f9c8d9 test: cover radio receive guard timing and playback progress 2026-10-08 14:30:21 +02:00
evgeny a1e8bfe80a android: keep radio VAD blocked until AudioTrack plays the receive tail 2026-10-08 14:28:08 +02:00
evgeny 06c35839ef chatgui: report radio output progress with device timing 2026-10-08 14:27:05 +02:00
evgeny fe7aabb44a radio: gate automatic VAD through receive and playback drain 2026-10-08 14:27:05 +02:00
evgeny c7c47d5ca3 android: use larger adaptive launcher icon with full background 2026-10-08 10:39:40 +02:00
evgeny dff2da0522 test: exercise Android replies through native bridge and media workers 2026-10-08 10:29:30 +02:00
evgeny 1ab51f3da1 android: translate channel reply actions and errors 2026-10-08 10:29:30 +02:00
evgeny 161af93347 android: connect channel reply navigation and camera context 2026-10-08 10:29:30 +02:00
evgeny f72fb177ba android: add reply menu and preserve drafts until submission completes 2026-10-08 10:29:30 +02:00
evgeny 30102f5f42 android: render reply quotes and support message long press 2026-10-08 10:29:30 +02:00
evgeny d28b7062d2 android: track saved replies and navigate original messages 2026-10-08 10:29:30 +02:00
evgeny 22e3c1b0a5 android: model channel reply drafts and native message references 2026-10-08 10:29:29 +02:00
evgeny 368f629948 android: expose reply submission and anchored history in bridge 2026-10-08 10:29:29 +02:00
evgeny 5f79d00f7a android: pass reply context through video preparation 2026-10-08 10:29:29 +02:00
evgeny 7aada92be9 android: preserve reply context while recording voice 2026-10-08 10:29:29 +02:00
evgeny 721160fbd9 android: carry channel reply references through file and photo sends 2026-10-08 10:29:08 +02:00
evgeny 4463f8870a Keep the viewed reply target stable until returning to latest messages 2026-10-08 00:50:17 +02:00
evgeny fde359b4af Set speaking state in the radio button color test fixture 2026-10-08 00:38:04 +02:00
evgeny ba0b21b999 Preserve newer composer edits when a reply finishes sending 2026-10-08 00:36:52 +02:00
evgeny adf1e9507a Fill reply history windows at boundaries and preserve read position 2026-10-08 00:36:52 +02:00
evgeny 3ea830fa00 Verify signed reply references across two peers over real PUSH 2026-10-08 00:32:06 +02:00
evgeny ec0666ca2a Keep quote activation separate from text selection gestures 2026-10-08 00:31:27 +02:00
evgeny 484d6f2fa4 Test signed replies, media completion and old-history lookup 2026-10-08 00:31:13 +02:00
evgeny a9e407a39f Test reply draft acknowledgements and quote clicks across content types 2026-10-08 00:30:08 +02:00
evgeny c6390575ad Translate channel reply actions and unavailable-message states 2026-10-08 00:30:07 +02:00
evgeny 7773a0c648 Keep return-to-latest action available in historical message windows 2026-10-08 00:27:02 +02:00
evgeny 38257a7f54 Connect reply sending, quote resolution and history navigation 2026-10-08 00:27:02 +02:00
evgeny 49e898b6f3 Deliver channel submission acknowledgements to the desktop composer 2026-10-08 00:24:35 +02:00
evgeny 562901c84f Add reply composer with cancellation and correlated send results 2026-10-08 00:24:20 +02:00
evgeny eebef4d14f Render clickable compact replies for text and media messages 2026-10-08 00:23:16 +02:00
evgeny 68df26d4a5 Read reply references and bounded history around message IDs 2026-10-08 00:21:58 +02:00
evgeny e811ac395a Preserve channel reply context through attachment preparation 2026-10-08 00:20:48 +02:00
evgeny 68037b25a5 Store signed replies by message ID and confirm channel submissions 2026-10-08 00:20:48 +02:00
evgeny 99e9b1ae85 Define channel reply references and submission result events 2026-10-08 00:19:35 +02:00
evgeny efebf8c5e8 Fix settings drafts, enlarge avatars, and show desktop version 2026-10-08 00:04:41 +02:00
evgeny f408abcf4e android: move advanced settings into a developer tab 2026-10-07 23:50:36 +02:00
evgeny 3aa0cd4c06 tests: add standalone Merkle sync reconnect and triangle stress test 2026-10-07 23:50:02 +02:00
evgeny 34a151e4cb chatgui: translate PTT latch and release hints 2026-10-07 21:44:14 +02:00
evgeny e4a84fd997 chatgui: verify latched PTT ownership and channel reset 2026-10-07 21:44:13 +02:00
evgeny 37485820b5 chatgui: latch radio PTT on double click and release on next press 2026-10-07 21:42:40 +02:00
evgeny 653853588a logging: preserve system diagnostics and inherit Android debug level 2026-10-07 21:21:33 +02:00
evgeny 1bb885fd11 logging: explain failed probes and RTT persistence errors 2026-10-07 21:15:39 +02:00
evgeny 7eb6d6ee68 logging: move socket mechanics and periodic probe decisions to trace 2026-10-07 21:14:38 +02:00
evgeny 15d460ee7c logging: explain BGP readiness, route selection and peer removal 2026-10-07 21:13:53 +02:00
evgeny a74a62079e logging: include REALITY handshake stage in connection failures 2026-10-07 21:11:34 +02:00
evgeny 6d54a7c102 logging: distinguish STCP probes from data link lifecycle 2026-10-07 21:11:12 +02:00
evgeny adc8b2a670 logging: describe STCP state and endpoint on timeout and close 2026-10-07 21:10:29 +02:00
evgeny b16a4995b7 logging: quiet routine audio and route polling, report audio recovery 2026-10-07 21:09:46 +02:00
evgeny e85a8c8310 logging: scope member file polling and worker traces to media 2026-10-07 21:09:27 +02:00
evgeny f3b1300628 Record Android radio speaker rollout and headless build issue 2026-10-07 19:35:46 +02:00
evgeny 2c407540a0 Test Android radio talk lifecycle and translate speaker status 2026-10-07 19:33:53 +02:00
evgeny e95fc090df Render Android speaker waves independently of local radio mute 2026-10-07 19:33:53 +02:00
evgeny bcda9b82f4 Track Android radio speakers and actual transmission by group 2026-10-07 19:33:53 +02:00
evgeny d5174262d8 Show speaking waves for locally muted radio members 2026-10-07 19:16:15 +02:00
evgeny 61818572cc Verify speaker timeout and record completed radio indication 2026-10-07 19:10:49 +02:00
evgeny 6496448569 Verify radio speaker icons through the bridge and actual PTT/VAD 2026-10-07 19:03:48 +02:00
evgeny 70fd5c077f Translate radio speaker status tooltips 2026-10-07 19:01:53 +02:00
evgeny e61fc8e392 Show silent, speaking and muted radio speakers in member rows 2026-10-07 19:01:53 +02:00
evgeny 5cbab70035 Track radio speakers independently of member list refreshes 2026-10-07 19:01:13 +02:00
evgeny 376695e410 Avoid Windows poll macro collision in activity monitor 2026-10-07 18:35:11 +02:00
evgeny c3468987cb Handle poll questions rendered as a standalone emoji 2026-10-07 17:33:26 +02:00
evgeny b6d8e822b4 Verify poll clicks preserve selection and message controls 2026-10-07 17:18:40 +02:00
evgeny ddcc36aa26 Open desktop chat polls with a single left click 2026-10-07 17:11:43 +02:00
evgeny 7e88d15e1d Validate unmanaged notification overlay independently of EWMH 2026-10-07 16:58:40 +02:00
evgeny 4a7f37b920 Use independent X11 notification overlay across desktops 2026-10-07 16:57:01 +02:00
evgeny bd163fffff Reapply all-desktop scope after notification mapping 2026-10-07 16:50:12 +02:00
evgeny e96e6b7751 Make desktop scope test independent of current workspace changes 2026-10-07 16:43:52 +02:00
evgeny 0d618964a7 Test popup remapping and keep headless input tests isolated 2026-10-07 16:38:33 +02:00
evgeny d62fae9e88 Verify notification desktop scope with a real window manager 2026-10-07 16:38:33 +02:00
evgeny 247479e411 Show Linux message notifications on all X11 desktops 2026-10-07 16:35:29 +02:00
evgeny 1108c773dc Own the independent popup and handle all keyboard mouse input 2026-10-07 16:05:34 +02:00
evgeny bc42df12f5 Keep notification independent of main window minimization 2026-10-07 16:05:33 +02:00
evgeny 2caa653f02 Trace cancellation of pending desktop activity queries 2026-10-07 16:02:10 +02:00
evgeny 16a9094770 Test live message metadata and document notification limits 2026-10-07 16:01:22 +02:00
evgeny c6cb3f0e8e Test notification timing, replacement, and activity fallbacks 2026-10-07 15:58:10 +02:00
evgeny 1da667b09e Complete notification translation and activity watcher cleanup 2026-10-07 15:57:15 +02:00
evgeny f2e35da1fe Wire notification platform dependencies and event diagnostics 2026-10-07 15:55:39 +02:00
evgeny 33c98a014f Notify about live incoming channel and direct messages 2026-10-07 15:54:25 +02:00
evgeny 261198ab47 Expose initial synchronization in channel message events 2026-10-07 15:53:39 +02:00
evgeny 77f2cdc34c Add message popup that expires after first user activity 2026-10-07 15:52:54 +02:00
evgeny 40b8e1a740 Add desktop user activity monitoring with platform fallbacks 2026-10-07 15:51:43 +02:00
evgeny 3279aa86ce Fix Windows system DLL detection in chatgui deployment 2026-10-07 14:07:32 +02:00
evgeny e5d8c34514 Fix desktop uasync readiness for radio member mute requests 2026-10-07 13:49:06 +02:00
evgeny 7e19cbaf3a Add local per-member radio mute controls on desktop and Android 2026-10-07 13:35:25 +02:00
evgeny a069d11ef9 Protect REALITY STCP traffic with authenticated TLS-like records 2026-10-07 12:30:45 +02:00
evgeny a49cf5434e Add randomized ETCP padding and isolate STCP CTR streams per connection 2026-10-07 10:45:42 +02:00
evgeny 1f5b42845b Document horizontal pickers and the signed single-reaction rule 2026-10-07 08:24:25 +02:00
evgeny b1bf094bfd Verify signed multi-reaction rejection and document the single-choice rule 2026-10-07 08:17:52 +02:00
evgeny 066fa8552d Display the reaction picker as one horizontal row in both clients 2026-10-07 08:14:50 +02:00
evgeny 0f14abd6c8 Test single reaction replacement, cancellation and multi-emoji rejection 2026-10-07 08:12:32 +02:00
evgeny a444f28134 Enforce one reaction per author and replace the previous emoji atomically 2026-10-07 08:12:32 +02:00
evgeny 87501a24fe Document reactions inside the timestamp row and device validation state 2026-10-07 02:06:01 +02:00
evgeny 033c24881c Verify reaction rows remain inside bubbles and grow with live updates 2026-10-07 02:00:13 +02:00
evgeny 3dbbe02f69 Keep desktop reactions and timestamp inside the bubble bottom row 2026-10-07 01:53:18 +02:00
evgeny 1f4266f8b1 Move Android reactions inside bubbles beside the timestamp 2026-10-07 01:45:43 +02:00
evgeny 2cf0f9c928 Document transparent reaction controls and verified desktop interactions 2026-10-07 01:35:13 +02:00
evgeny aaa05e761e Check reaction clicks against downloadable media and portable preview paths 2026-10-07 01:30:04 +02:00
evgeny 4f0870b961 Verify transparent reaction footer clicks across text and media layouts 2026-10-07 01:28:56 +02:00
evgeny fc79fa7345 Keep message footer layout and click gesture states consistent 2026-10-07 01:27:04 +02:00
evgeny f71e5531e0 Open reaction picker from desktop heart and toggle existing reactions 2026-10-07 01:22:34 +02:00
evgeny 00ca006d26 Render and hit-test reaction footer for every desktop message type 2026-10-07 01:21:52 +02:00
evgeny 29ee55d751 Enlarge desktop chat and member avatars 2026-10-07 01:18:31 +02:00
evgeny aa58c7fd3d Place transparent outline reaction heart below Android message bubbles 2026-10-07 01:16:33 +02:00
evgeny f8d0acb38d Record root certificate repair and pending SM device verification 2026-10-07 00:56:41 +02:00
evgeny 0218ea9ddd Require channel signatures for root feedback authors and verify profile copies 2026-10-07 00:47:32 +02:00
evgeny 9299c95f10 Verify root formation and invitation certificate replication 2026-10-07 00:46:36 +02:00
evgeny a9a65d53bf Preserve invitation certificates and accept confirmed roots without profile changes 2026-10-07 00:44:50 +02:00
evgeny 7cddb47edc Record verified SM and local history repair 2026-10-07 00:33:52 +02:00
evgeny 8cd54f9802 Verify restored schema constraints and legacy index fixture 2026-10-07 00:27:35 +02:00
evgeny a014d518bf Test atomic history schema repair and preserved message data 2026-10-07 00:26:59 +02:00
evgeny 2f5a49b011 Repair existing chat history tables with stable message IDs 2026-10-07 00:25:11 +02:00
evgeny 918a3cc061 Merge chat polls and reactions into master 2026-10-06 23:08:07 +02:00
evgeny 1f026baf45 Show a circular crop preview in the desktop avatar editor 2026-10-06 23:05:21 +02:00
evgeny a8c81f7e2b Record verified poll implementation and completed checks 2026-10-06 22:56:31 +02:00
evgeny 255853dd76 Document complete poll protocol and verified recovery behavior 2026-10-06 22:47:06 +02:00
evgeny 587a980081 Document poll creation, voting and reaction commands 2026-10-06 22:43:13 +02:00
evgeny bbc8b7693a Restart member and feedback synchronization over existing transports 2026-10-06 22:40:47 +02:00
evgeny 9edc76e5eb Fix Android avatar crop layout and circular preview
Keep the crop actions inside the available dialog window, show a circular mask, and clamp gesture limits to prevent float rounding crashes.
2026-10-06 22:37:04 +02:00
evgeny 7f4a1a66fa Include transport state definitions in poll network regression 2026-10-06 22:33:52 +02:00
evgeny 0c16c2b09a Wait for authenticated bootstrap transport before opening group requests 2026-10-06 22:33:35 +02:00
evgeny 67d1718450 Measure proxy test durations with a monotonic clock 2026-10-06 22:31:53 +02:00
evgeny e86de44259 Test poll synchronization through three nodes and chat restart 2026-10-06 22:30:52 +02:00
evgeny 4966600d52 Localize desktop interaction errors 2026-10-06 22:21:13 +02:00
evgeny 6686dd1815 Translate desktop poll and reaction controls 2026-10-06 22:21:13 +02:00
evgeny 8dc7595e46 Preserve Android feedback state and supplementary Unicode characters 2026-10-06 22:15:44 +02:00
evgeny 1d05ff34c6 Connect Android poll screens and localize interaction controls 2026-10-06 22:15:04 +02:00
evgeny 44e0b7849e Add Android poll voting, results and message reaction components 2026-10-06 22:14:29 +02:00
evgeny 0a615913eb Drive Android feedback commands and live updates through the core thread 2026-10-06 21:45:59 +02:00
evgeny 8f8c8c267f Add typed poll and reaction states to Android message models 2026-10-06 21:45:59 +02:00
evgeny 2c31e3fe03 Expose UTF-8 feedback commands and full message identities on Android 2026-10-06 21:43:21 +02:00
evgeny 39e94fdfd3 Add message reaction menus and distinguish own reactions 2026-10-06 21:39:14 +02:00
evgeny cf869770fb Add desktop poll creation, voting and live result dialogs 2026-10-06 21:39:13 +02:00
evgeny b0933eb282 Keep avatar cache pruning tied to the originating Android account 2026-10-06 21:37:18 +02:00
evgeny ebc96712a2 Track feedback by message identity in desktop UI 2026-10-06 21:36:43 +02:00
evgeny c1048686d1 Route feedback state and command results to the desktop thread 2026-10-06 21:34:38 +02:00
evgeny 0a05a2095e Read stable message identities and decode escaped text in desktop 2026-10-06 21:34:38 +02:00
evgeny 52f4628fe0 Bound avatar manifest sizes before numeric conversion 2026-10-06 21:34:15 +02:00
evgeny e068fe5d3a Test poll codecs, voting rules and delayed source messages 2026-10-06 21:31:20 +02:00
evgeny da2c13dcf1 Add CLI poll creation, voting and emoji reaction commands 2026-10-06 21:26:37 +02:00
evgeny f99a8c1da2 Expose polls and reactions through headless control safely 2026-10-06 21:26:37 +02:00
evgeny ef476bf4e2 Use canonical reaction and answer payloads in feedback tests 2026-10-06 21:24:53 +02:00
evgeny 48d7f2b21b Build poll modules and adapt media insertion callbacks 2026-10-06 21:24:53 +02:00
evgeny 17444b8c8a Evaluate delayed answers after their source message arrives 2026-10-06 21:24:14 +02:00
evgeny 60b4870549 Pass stable identities to insertion callbacks and bound signed bodies 2026-10-06 21:24:13 +02:00
evgeny 865e4cda59 Log delayed answer validation and keep JSON percentages locale independent 2026-10-06 21:23:37 +02:00
evgeny e6db9fef60 Validate feedback data and provide poll command snapshots 2026-10-06 21:23:37 +02:00
evgeny 0af35630d1 Expose full message data and stable identities in listings 2026-10-06 21:17:24 +02:00
evgeny a4ca31f406 Return submitted message identity and encode JSON safely 2026-10-06 21:17:24 +02:00
evgeny d0aa60fe1a Define canonical poll, answer and reaction formats 2026-10-06 21:15:57 +02:00
evgeny d40f58d79a Add message identities and plan the remaining feedback work 2026-10-06 21:12:53 +02:00
evgeny 3e1cc8af85 Map avatar crop frames using full original dimensions on both clients 2026-10-06 21:10:24 +02:00
evgeny 8676893d59 Record feedback implementation milestone and remaining work 2026-10-06 20:17:48 +02:00
evgeny 04ff801531 Document Merkle v3 and signed feedback state contracts 2026-10-06 20:11:25 +02:00
evgeny 6437bf780b Include feedback source in the core library source list 2026-10-06 20:09:48 +02:00
evgeny 4f4e63bb0b Test feedback signatures, versions, cancellation and atomic pages 2026-10-06 20:08:53 +02:00
evgeny f6cc3b6e53 Make feedback roots depend on signed state and validate rebuilt keys 2026-10-06 20:07:44 +02:00
evgeny 982e5a06ab Integrate feedback tables with channel and sync lifecycle 2026-10-06 20:06:39 +02:00
evgeny 8121f93d2e Build feedback model and expose committed state events 2026-10-06 20:06:38 +02:00
evgeny 641a8318a8 Add signed versioned feedback storage and Merkle adapter 2026-10-06 20:05:18 +02:00
evgeny a0fbf51be0 Describe avatar object paths consistently 2026-10-06 20:04:40 +02:00
evgeny 17dd06221a Log Android gallery selections and finish image gestures safely 2026-10-06 20:04:40 +02:00
evgeny cdc5474279 Document avatar bundles, crop selection and original-image galleries 2026-10-06 20:02:45 +02:00
evgeny cee3228e5f Separate each Android gallery swipe from pinch and pan gestures 2026-10-06 20:02:45 +02:00
evgeny 864a250eea Preserve input cursor when member page outputs alias it 2026-10-06 20:02:41 +02:00
evgeny 3f4df4233b Keep member avatar drags separate from viewer clicks 2026-10-06 20:01:38 +02:00
evgeny 1f9dbd9dea Open desktop message avatars only after a completed click 2026-10-06 20:01:38 +02:00
evgeny 7d69404532 Verify five centered previews while navigating six avatar originals 2026-10-06 20:00:58 +02:00
evgeny 49dc837df2 Correct all member dataset arguments in callers 2026-10-06 19:59:43 +02:00
evgeny f0314ab51c Test dataset isolation and colliding cursor prefixes 2026-10-06 19:59:00 +02:00
evgeny 3be5cdd365 Show Android preview loading states and retry failed neighbors 2026-10-06 19:58:37 +02:00
evgeny 96af98f063 Exercise avatar crop gestures, gallery navigation and EXIF originals 2026-10-06 19:58:36 +02:00
evgeny f6bfd36a6c Include dataset identity in Merkle diagnostics 2026-10-06 19:57:58 +02:00
evgeny 1350c95db6 Identify desktop crop controls for interaction checks 2026-10-06 19:57:32 +02:00
evgeny bc7864466c Offer retries for desktop avatar catalog and image failures 2026-10-06 19:57:32 +02:00
evgeny fad96603a7 Display gallery loading and failure placeholders in the image viewer 2026-10-06 19:57:32 +02:00
evgeny 894b24698e Update Merkle integration tests and channel index cleanup 2026-10-06 19:57:25 +02:00
evgeny 5e146f20bc Adapt member sync and protocol tests to dataset cursors 2026-10-06 19:56:52 +02:00
evgeny 539bfd6db9 Extend Merkle sessions with datasets and full record cursors 2026-10-06 19:56:17 +02:00
evgeny c36fd3bfc8 Remove obsolete Android PNG user-avatar preparation 2026-10-06 19:55:20 +02:00
evgeny feccea21a5 Keep desktop crop workers owned until their dialog closes 2026-10-06 19:55:20 +02:00
evgeny 37b80b612b Restore Android gallery selections and validate editor source formats 2026-10-06 19:55:20 +02:00
evgeny 5b4b17ae49 Keep selected Android originals while the catalog finishes loading 2026-10-06 19:51:54 +02:00
evgeny 43c300cba3 Release Android crop sources rejected after account changes 2026-10-06 19:51:53 +02:00
evgeny cbe6da09ee Translate desktop avatar editor and gallery controls 2026-10-06 19:51:53 +02:00
evgeny 27fd9ee62d Share avatar metadata downloads and cancel closed desktop galleries 2026-10-06 19:48:24 +02:00
evgeny 6bd6ea540c Cancel avatar transfers after their last Android viewer closes 2026-10-06 19:48:24 +02:00
evgeny 7e5b60aa10 Include WebP runtime dependencies and avatar test painter 2026-10-06 19:48:24 +02:00
evgeny 7d71b08def Validate avatar object types and distinguish original downloads 2026-10-06 19:46:59 +02:00
evgeny a221452cb6 Correct Kotlin types in avatar catalog and crop coordinates 2026-10-06 19:46:59 +02:00
evgeny 863441c418 Test Android avatar catalog pagination and updated member snapshots 2026-10-06 19:45:19 +02:00
evgeny ab22277e7b Test avatar originals, selected lossy crops and storage limits 2026-10-06 19:44:56 +02:00
evgeny 32eaf9df04 Translate Android avatar crop and empty-gallery states 2026-10-06 19:43:51 +02:00
evgeny af6cd31e71 Open Android avatar galleries with originals and five previews 2026-10-06 19:43:27 +02:00
evgeny 87b8c6bd3a Use exact image coordinates in the desktop crop editor 2026-10-06 19:42:22 +02:00
evgeny 5f3725b72f Add Android avatar crop selection before publication 2026-10-06 19:42:22 +02:00
evgeny d1080129d2 Publish complete Android avatar bundles after crop confirmation 2026-10-06 19:41:02 +02:00
evgeny ea6b895df9 Load Android gallery objects and catalogs through the shared cache 2026-10-06 19:41:01 +02:00
evgeny f27419165d Preserve Android avatar originals and encode selected WebP crops 2026-10-06 19:38:40 +02:00
evgeny 6e9a50f2ec Bridge Android avatar catalogs and per-object transfer limits 2026-10-06 19:37:45 +02:00
evgeny 07aa436380 Decode avatar manifests and paginated catalogs on Android 2026-10-06 19:37:45 +02:00
evgeny c4c11ad813 Build avatar UI and deploy the desktop WebP codec 2026-10-06 19:36:35 +02:00
evgeny fd8054bc7b Open user avatar galleries from desktop member icons 2026-10-06 19:36:35 +02:00
evgeny 3a793e25b3 Open user avatar galleries from desktop messages 2026-10-06 19:36:34 +02:00
evgeny 9970b2235c Show desktop avatar originals with five centered previews 2026-10-06 19:36:00 +02:00
evgeny 4134200b4e Allow avatar galleries to display validated cached images 2026-10-06 19:35:59 +02:00
evgeny ccae89fb60 Add desktop square crop editor before avatar upload 2026-10-06 19:35:59 +02:00
evgeny 1a936f33ef Upload complete avatar bundles and page desktop galleries 2026-10-06 19:34:10 +02:00
evgeny 68fb29e385 Add avatar gallery sources and manifest-aware desktop cache 2026-10-06 19:33:24 +02:00
evgeny f0cc198f72 Prepare avatar originals, WebP crops and hashed manifests 2026-10-06 19:32:22 +02:00
evgeny 17491082d4 Validate signed profile avatar manifest references 2026-10-06 19:29:42 +02:00
evgeny c80e82d104 Define member avatar references as manifest objects 2026-10-06 19:29:37 +02:00
evgeny 50efddd5f0 Allow immutable avatar originals and manifests in storage 2026-10-06 19:29:17 +02:00
evgeny 40eafafe3d chatgui: verify drag highlight cleanup and attachment file picker reuse 2026-10-06 19:11:12 +02:00
evgeny 348cd855b9 chatgui: detach file drop callbacks before composer child destruction 2026-10-06 19:06:37 +02:00
evgeny a175129f93 chatgui: complete audio dependencies for composer integration tests 2026-10-06 19:04:31 +02:00
evgeny 9c7442544b chatgui: add Qt integration tests for file drops and recipient changes 2026-10-06 19:02:04 +02:00
evgeny cc8e47cfc8 chatgui: localize file drop hints and attachment rejection messages 2026-10-06 19:00:18 +02:00
evgeny 0279ed84a9 chatgui: stage dropped files through the attachment composer 2026-10-06 18:58:33 +02:00
evgeny 7b1143b9d4 android: hide download overlay on locally available photos 2026-10-06 17:57:36 +02:00
evgeny 27fb1426d9 android: cover decimal channel IDs from SM in avatar regression tests 2026-10-06 17:34:03 +02:00
evgeny eae3ef5c32 android: parse decimal channel IDs for avatar requests and group keys 2026-10-06 17:32:43 +02:00
evgeny b3c0a2fa7b android: harden avatar cache reads and refresh current download sources 2026-10-06 16:39:26 +02:00
evgeny 15dbb6fe51 android: test avatar event framing, limits and member updates 2026-10-06 16:32:36 +02:00
evgeny 9c70eab075 android: cancel avatar operations before native teardown and bound image preparation 2026-10-06 16:30:54 +02:00
evgeny 15d0772a20 android: preserve avatar references in JSON refresh and live member snapshots 2026-10-06 16:29:06 +02:00
evgeny 57888f8d9e android: display member avatars in conversations and member details 2026-10-06 16:27:35 +02:00
evgeny c77066162a android: show group icons and open properties from chat header 2026-10-06 16:25:51 +02:00
evgeny b9d41d179d android: add avatar editors and localized group properties dialog 2026-10-06 16:24:25 +02:00
evgeny 73019cfd83 android: add shared avatar components and guard picker account identity 2026-10-06 16:22:24 +02:00
evgeny 22aa5d47a5 android: load and cache user and signed group avatars asynchronously 2026-10-06 16:20:45 +02:00
evgeny 8efe075679 android: add asynchronous avatar JNI operations and wire models 2026-10-06 16:15:00 +02:00
evgeny 714370a1a2 Verify direct deployment after a failed Qt deployment tool 2026-10-06 15:53:03 +02:00
evgeny f316554ca3 Retain deployment diagnostics and model executable runtime imports 2026-10-06 15:48:10 +02:00
evgeny e7be94a3d2 Test Qt runtime deployment and missing plugin dependencies 2026-10-06 15:46:46 +02:00
evgeny c4217a8aa6 Verify runtime dependencies and deploy matching Qt plugins every build 2026-10-06 15:44:58 +02:00
evgeny 3d277349be Deploy the selected Qt version and recognize Windows system DLLs 2026-10-06 15:40:54 +02:00
evgeny c81e8e5025 Link Winsock after uasync and include socket headers first 2026-10-06 15:11:16 +02:00
evgeny e9e38ee029 Guard the file protocol against the Windows menu macro 2026-10-06 14:55:31 +02:00
evgeny ed3815a406 Use the portable remove command in the browser and storage tests 2026-10-06 14:54:23 +02:00
evgeny fe03feaf4a Avoid the Win32 MF_REMOVE macro in the file protocol 2026-10-06 14:54:23 +02:00
evgeny e8365fdec6 Upgrade group avatar columns before notifying database readiness 2026-10-06 14:04:49 +02:00
evgeny 5c772aeecf Preserve channel identity in member adapter fixtures 2026-10-06 14:04:49 +02:00
evgeny 2bcba58131 Reject group avatar commands outside a running chat service 2026-10-06 13:59:17 +02:00
evgeny b6a5f98d41 Document 16 KiB signed group avatars and 4 KiB wire blocks 2026-10-06 13:57:12 +02:00
evgeny d0173e1b73 Test atomic schema upgrades and report precise avatar validation errors 2026-10-06 13:57:12 +02:00
evgeny f8d95fcb25 Initialize avatar peers from the current group session epoch 2026-10-06 13:52:19 +02:00
evgeny 35ce2a2b93 Check group avatar encoding, rendering and key-based controls 2026-10-06 13:51:18 +02:00
evgeny 3b47a56076 Trace group avatar assembly resets and block mismatches 2026-10-06 13:49:54 +02:00
evgeny 46f4ce7091 Test real group avatar block delivery, permissions and recovery 2026-10-06 13:48:14 +02:00
evgeny 4062ecdfb1 Display group avatars and restrict editing to group key holders 2026-10-06 13:44:49 +02:00
evgeny 8e3ff6fd81 Deliver group avatar publication results through the GUI bridge 2026-10-06 13:44:49 +02:00
evgeny 2f9dd6a27b Decode and prepare bounded group avatar images outside the GUI thread 2026-10-06 13:43:49 +02:00
evgeny a816b842e5 Read group avatar metadata separately from image bytes 2026-10-06 13:43:49 +02:00
evgeny 56897368b3 Own group avatar synchronization in the chat service lifecycle 2026-10-06 13:41:55 +02:00
evgeny f67f090b2a Synchronize signed group avatars in bounded 4 KiB blocks 2026-10-06 13:41:29 +02:00
evgeny e3745f279e Store signed group avatars without replacing channel keys 2026-10-06 13:37:18 +02:00
evgeny 8173677475 Avoid refreshing avatar controls on unchanged member telemetry 2026-10-06 13:04:57 +02:00
evgeny 74bd4eed7c Keep outdated avatar transfers from delaying new references 2026-10-06 13:03:53 +02:00
evgeny ae461e746f Update Android consumers for extended member snapshots 2026-10-06 13:02:01 +02:00
evgeny 8f83167c0f Forward full join profiles and document canonical profile lengths 2026-10-06 12:58:00 +02:00
evgeny 6d3187db57 Keep profile controls consistent with the saved avatar server 2026-10-06 12:56:20 +02:00
evgeny 5276cd0fa0 Simplify profile updates and report database read failures 2026-10-06 12:54:44 +02:00
evgeny 80c81502fb Protect avatar paths across platforms and initialize join fixture nodes 2026-10-06 12:53:05 +02:00
evgeny 9bfdf3ea41 Allow avatar replacement alongside downloads and correct join fixtures 2026-10-06 12:51:22 +02:00
evgeny dc156c7f2b Test bounded downloads and late completion after avatar replacement 2026-10-06 12:49:26 +02:00
evgeny d946a1b93a Finalize unsigned initial profiles before channel bootstrap 2026-10-06 12:48:20 +02:00
evgeny cebd138190 Expose profile diagnostics in verbose join integration runs 2026-10-06 12:47:20 +02:00
evgeny 8b327a3f27 Bound upload cache growth and reject stale transfer completions 2026-10-06 12:46:32 +02:00
evgeny 972910c763 Verify profile signatures survive avatar and display name updates 2026-10-06 12:45:45 +02:00
evgeny 9842de7ab7 Document avatar storage, profile exchange and client caching 2026-10-06 12:45:13 +02:00
evgeny c04f51d424 Use bounded 16-bit profile lengths in join member records 2026-10-06 12:44:18 +02:00
evgeny 76c02012eb Preserve complete signed profiles in channel bootstrap messages 2026-10-06 12:44:18 +02:00
evgeny c0a4bc7d89 Persist the desired avatar reference atomically 2026-10-06 12:43:11 +02:00
evgeny 9279ded7f3 Read complete signed profiles and escape initial display names 2026-10-06 12:43:11 +02:00
evgeny 3e1641aaf0 Persist avatar removal intent and prioritize profile changes 2026-10-06 12:41:05 +02:00
evgeny f2d2e6be8f Test avatar immutability, hash validation and quota accounting 2026-10-06 12:40:07 +02:00
evgeny 405755f06a Reuse shared channel avatars in direct message conversations 2026-10-06 12:40:07 +02:00
evgeny b8ddf0f52d Translate avatar profile controls and operation statuses 2026-10-06 12:38:51 +02:00
evgeny e642551dfe Expose signed storage roles independently of route priority 2026-10-06 12:38:11 +02:00
evgeny 2fe5f34c5c Trace avatar discovery and profile events for integration checks 2026-10-06 12:37:25 +02:00
evgeny 8fb9129300 Verify large signed profiles alongside full owner records 2026-10-06 12:36:35 +02:00
evgeny eceb69c58e Test avatar publication, channel replication and persistent cache 2026-10-06 12:35:46 +02:00
evgeny 7582509792 Protect pending avatar uploads while bounding disk cache retention 2026-10-06 12:35:45 +02:00
evgeny 1988afa84d Notify profile changes with actual member properties 2026-10-06 12:33:26 +02:00
evgeny 247e3a2efe Add avatar upload, preview and removal to profile settings 2026-10-06 12:33:00 +02:00
evgeny 694ed8e263 Display cached user avatars in member lists and chat messages 2026-10-06 12:32:33 +02:00
evgeny 78bed5efe4 Route avatar events alongside file browser events in ChatGUI 2026-10-06 12:32:02 +02:00
evgeny 8ae45e9e39 Manage avatar replication, background downloads and shared cache 2026-10-06 12:31:16 +02:00
evgeny f91251be14 Add bounded persistent avatar cache and image normalization 2026-10-06 12:28:59 +02:00
evgeny e8a3d5fa16 Bound avatar transfers and enforce immutable hashed uploads 2026-10-06 12:27:32 +02:00
evgeny cbb1a03ccd Define canonical avatar names and size limits 2026-10-06 12:27:32 +02:00
evgeny 61ef23b885 Include avatar references in member snapshots and change events 2026-10-06 12:27:07 +02:00
evgeny 4fbb1dafe1 Preserve profile attributes and publish signed avatar references 2026-10-06 12:26:38 +02:00
evgeny 8029b6e3f5 Extend signed member profiles to 1024 bytes 2026-10-06 12:25:21 +02:00
evgeny 02bd10b005 Document incremental object counts and quota protocol version 4 2026-10-06 11:36:30 +02:00
evgeny 9a06d19984 Test incremental counts, empty replacements and startup-only scans 2026-10-06 11:33:57 +02:00
evgeny e6bf925a94 Translate file and directory statistics in the quota display 2026-10-06 11:29:43 +02:00
evgeny 64d46cdef0 Display file and directory totals in client quota snapshots 2026-10-06 11:29:43 +02:00
evgeny d1034cb4ea Maintain file and directory statistics incrementally per user 2026-10-06 11:25:18 +02:00
evgeny c8236373b1 Extend quota snapshots with file and directory counts 2026-10-06 11:25:18 +02:00
evgeny e76dc6cb82 Report actual directory creation separately from durability errors 2026-10-06 11:25:18 +02:00
evgeny 69f04dec87 Document per-user quotas and the client quota query 2026-10-06 00:29:28 +02:00
evgeny 092e3e3cdc Validate quota scan failures and deny unauthorized quota queries 2026-10-06 00:29:28 +02:00
evgeny fb9e7c3351 Translate quota display and reservation details 2026-10-06 00:25:07 +02:00
evgeny db6acf8662 Test quota display, stale responses and startup directory retries 2026-10-06 00:25:07 +02:00
evgeny 594017ba5f Test user quota isolation, reservations, restarts and wire queries 2026-10-06 00:22:17 +02:00
evgeny 4fdecb697b Show live user storage quota in the member file browser 2026-10-06 00:18:00 +02:00
evgeny 359a327ec4 Enforce per-user reservations and initialize storage at startup 2026-10-06 00:16:20 +02:00
evgeny 3b641a2423 Add the file quota query and per-user quota configuration 2026-10-06 00:14:03 +02:00
evgeny 3354c0b374 Initialize per-user file quota accounts from the storage tree 2026-10-06 00:11:21 +02:00
evgeny 25e2ffeea7 Stream member files with router backpressure and parallel transfer handles 2026-10-05 23:36:49 +02:00
evgeny f7e1752fc2 Document focused member file debug tracing 2026-10-05 21:52:12 +02:00
evgeny 977748b16c Expose fork ownership errors in file debug traces 2026-10-05 21:43:44 +02:00
evgeny c259a7330b Trace file router sessions and crypto decisions in debug 2026-10-05 21:41:46 +02:00
evgeny 0706ccce8a Trace browser state, transfer I/O and daemon PID 2026-10-05 21:36:43 +02:00
evgeny aca10e8268 Trace file bridge callbacks and use scoped VAD test logs 2026-10-05 21:34:39 +02:00
evgeny e913a27f0c Trace file storage and worker lifecycle in debug 2026-10-05 21:33:04 +02:00
evgeny 8982bb034e Move legacy sound and attachment errors to media 2026-10-05 21:30:37 +02:00
evgeny 0773a82342 Keep debug focused on file browser event delivery 2026-10-05 21:30:01 +02:00
evgeny b771e95997 Clear legacy GUI bridge and list messages from debug 2026-10-05 21:28:45 +02:00
evgeny 5b78ec04f6 Move old radio and attachment diagnostics out of debug 2026-10-05 21:26:09 +02:00
evgeny 5dea9394bf Trace member file requests in debug category 2026-10-05 21:25:02 +02:00
evgeny 5d1b8d26e7 Daemonize before creating core workers 2026-10-05 21:19:19 +02:00
evgeny 78a655bb05 Add asynchronous member file storage and desktop browser 2026-10-05 18:44:58 +02:00
evgeny 27d93ecaf9 Add English and Russian ChatGUI interface translations 2026-10-05 16:55:43 +02:00
evgeny 972c6b7f0a Raise rlottie shape budget and log truncated animations 2026-10-05 16:48:00 +02:00
evgeny 7423133229 Build bundled rlottie automatically before Windows ChatGUI 2026-10-05 14:41:03 +02:00
evgeny 5e309c27ca Vendor rlottie sources with CMake and MinGW build adjustments 2026-10-05 14:31:35 +02:00
evgeny 8feb7902b9 Search local rlottie build for its CMake package configuration 2026-10-05 14:15:25 +02:00
evgeny bba44fbe11 Always copy rlottie DLL during ChatGUI runtime deployment 2026-10-05 13:55:43 +02:00
evgeny bc6d372064 Treat imagehlp and bcryptprimitives as Windows system DLLs 2026-10-05 13:43:57 +02:00
evgeny e4c591e1e6 Disable ZXing size optimization for MinGW GCC string link issue 2026-10-05 13:38:16 +02:00
evgeny 05064f7f3d Refresh compiler runtime DLLs before Windows ChatGUI builds 2026-10-05 13:22:16 +02:00
evgeny 3cfa9f8da1 Compare cc1 startup across directories and inspect runtime DLLs 2026-10-05 13:12:11 +02:00
evgeny 586f62fd0a Diagnose Opus bands compilation and replay native Ninja command 2026-10-05 13:07:55 +02:00
evgeny 2c5293bff0 Extend compiler diagnostics with standalone and CMake Opus checks 2026-10-05 13:02:08 +02:00
evgeny a154bacffb Add MSYS2 UCRT64 compiler diagnostic scripts 2026-10-05 12:58:40 +02:00
evgeny 9aaac3cb20 Exclude POSIX tcp_io test scenarios from Windows compilation 2026-10-05 12:27:15 +02:00
evgeny 577d1bd72f Handle delayed TCP delivery in etcpmon regression checks 2026-10-05 12:22:39 +02:00
evgeny d62916edf0 Validate etcpmon response strings and close failed streams 2026-10-05 12:20:25 +02:00
evgeny 45efaf095d Add Windows regression coverage for etcpmon refresh lifecycle 2026-10-05 12:14:04 +02:00
evgeny 24906283fe Refresh etcpmon connections and preserve selection by peer ID 2026-10-05 12:11:43 +02:00
evgeny 9465ed4939 Fix etcpmon response caches and pending request lifecycle 2026-10-05 12:08:05 +02:00
evgeny 0dbdd47130 Fix Windows IPv6 socket option and const link address 2026-10-05 12:00:10 +02:00
evgeny 341da73398 Fix Windows getsockopt argument in TCP error callback 2026-10-05 11:46:54 +02:00
evgeny ba7146f90a Fix HTTP proxy framing, keep-alive and stream lifecycle 2026-10-05 09:27:23 +02:00
evgeny 9005c67b8b Skip Windows DLL deployment when runtimes are present 2026-10-05 09:27:11 +02:00
evgeny 0b72364f10 Recognize DirectWrite and spooler system imports 2026-10-04 23:00:23 +02:00
evgeny be9a953136 Read Windows DLL import dumps through a temporary file 2026-10-04 22:49:17 +02:00
evgeny 6e4b1ae9c4 Trace Windows import parsing and dependency resolution 2026-10-04 22:41:08 +02:00
evgeny ba2bafe56e Diagnose Windows DLL scanning and recognize system imports 2026-10-04 22:25:11 +02:00
evgeny d02c55dbcd Document web link handling, validation and Q8 verification 2026-10-04 19:18:00 +02:00
evgeny 4fcf45d545 Accept browser URL paths on Android and drag within the tested link 2026-10-04 19:12:18 +02:00
evgeny ec856cc73f Verify web link geometry, full addresses, mixed schemes and drag copying 2026-10-04 19:08:39 +02:00
evgeny 4ce7e29a37 Share URL boundary fixtures between Android and Qt tests 2026-10-04 19:08:39 +02:00
evgeny dc2b6c3d68 Keep invitation and gesture regressions on the generic link API 2026-10-04 19:07:11 +02:00
evgeny 2e41610693 Open Android web links from shared channel and PM message UI 2026-10-04 19:06:44 +02:00
evgeny e2472cb5c3 Localize failures opening external message links 2026-10-04 19:06:44 +02:00
evgeny c191b777b7 Annotate Android web links without altering addresses containing emoji 2026-10-04 19:06:44 +02:00
evgeny 0a060d04ca Parse Android message links with matching punctuation rules 2026-10-04 19:05:09 +02:00
evgeny a76ba87501 Open HTTP and HTTPS messages through the desktop URL handler 2026-10-04 19:05:08 +02:00
evgeny 01fa1bc552 Route message link activation through the Qt conversation view 2026-10-04 19:05:08 +02:00
evgeny 5b321c6304 Generalize Qt link gestures while preserving drag selection 2026-10-04 19:04:11 +02:00
evgeny 3482e4a327 Share Qt text layout for web links and invitations 2026-10-04 19:04:11 +02:00
evgeny 394ac93dc4 Extract message links with explicit schemes and punctuation boundaries 2026-10-04 19:03:11 +02:00
evgeny 93c0c5bdfc Show channel member inviter in Android details 2026-10-04 18:34:17 +02:00
evgeny b6fd489b8e Record compact invitation validation and Q8 installation 2026-10-04 18:21:08 +02:00
evgeny 35266d2a31 Verify copy through Qt keyboard action and log Android invite presentation 2026-10-04 18:12:58 +02:00
evgeny d14babea33 Create signed test channel with its final invitation title 2026-10-04 18:12:23 +02:00
evgeny af27eaa33b Size invitation JSON buffers to the escaping contract 2026-10-04 18:11:54 +02:00
evgeny ec7ec2a229 Document localized invitation titles and compact link presentation 2026-10-04 18:11:08 +02:00
evgeny f70d5c7460 Verify invitation title delivery and one-line full-link actions 2026-10-04 18:09:41 +02:00
evgeny 6ad89a4f6a Elide Qt invitation links with consistent layout and full-address selection 2026-10-04 18:08:43 +02:00
evgeny 12e09cb0ed Render one-line Android invitations and retain full links for copy 2026-10-04 18:07:46 +02:00
evgeny 0ce6e9e83a Expose invitation group tags and localized Android titles 2026-10-04 18:06:55 +02:00
evgeny 306aaa94ba Carry encrypted group name metadata in PM invitations 2026-10-04 18:06:26 +02:00
evgeny be65962e96 Record final history recovery validation 2026-10-04 17:57:04 +02:00
evgeny a6aea51ff3 Document invitation history recovery and device verification 2026-10-04 17:46:20 +02:00
evgeny 607bd5d475 Report history wait reasons and registration failures precisely 2026-10-04 17:20:07 +02:00
evgeny 387f95208d Keep message content type alive through JSON serialization 2026-10-04 17:16:58 +02:00
evgeny fb92f1a8c9 Verify history recovery when a group session loses readiness 2026-10-04 17:10:49 +02:00
evgeny 4cd52c27d5 Include transport definition in history fault injection test 2026-10-04 16:57:06 +02:00
evgeny a5c616ba0f Exercise history retry after a lost initial exchange 2026-10-04 16:56:24 +02:00
evgeny 65264137f8 Apply JOIN metadata through the transactional member model 2026-10-04 16:55:00 +02:00
evgeny b390f3c28f Cover pre-invitation history with both synchronization roles 2026-10-04 16:48:01 +02:00
evgeny 274f4f2d63 Prepare explicit group sessions in history protocol fixtures 2026-10-04 16:47:01 +02:00
evgeny eaac611465 Gate history on member synchronization and group readiness 2026-10-04 16:45:47 +02:00
evgeny 6a67cc2038 Prepare channel history before enabling network synchronization 2026-10-04 16:40:32 +02:00
evgeny 865657b3bd Expose group peer readiness transitions to subscribers 2026-10-04 16:39:19 +02:00
evgeny 5caa1131c8 Test Android member radio flags and update preservation 2026-10-04 16:10:41 +02:00
evgeny cf77fffaeb Keep the stroke import used by radio controls 2026-10-04 16:07:08 +02:00
evgeny 51467296c3 Test radio member snapshots, updates and route withdrawal 2026-10-04 16:05:40 +02:00
evgeny 334521ce3f Display active radios in Android member rows 2026-10-04 16:02:57 +02:00
evgeny 47082c4e2e Preserve Android radio presence across member refreshes 2026-10-04 16:02:57 +02:00
evgeny 658c248867 Request Android member snapshots on the core thread 2026-10-04 16:00:41 +02:00
evgeny 6c5c1ef0a0 Show enabled radios in desktop member rows 2026-10-04 15:59:45 +02:00
evgeny 0f9210e491 Share the desktop portable radio icon painter 2026-10-04 15:59:45 +02:00
evgeny 9dd2dffc80 Expose live radio subscriptions in member updates 2026-10-04 15:58:54 +02:00
evgeny 81d71690c2 Document PM invitation flow, lifetime and verification 2026-10-04 15:55:42 +02:00
evgeny 38c4c0772b Use explicit cursor index type for Qt 5 and Qt 6 2026-10-04 15:54:06 +02:00
evgeny 69442dcbb8 Start wrapped-link selection test inside the first link line 2026-10-04 15:52:18 +02:00
evgeny 17179c9c4a Use invite text layout for selection and wrapped emoji positions 2026-10-04 15:51:51 +02:00
evgeny 0e5778c013 Reuse PM automatic route resolution and check persistence after successful send 2026-10-04 15:50:38 +02:00
evgeny f02894f164 Release pending invitation dialogs when Android chat stops 2026-10-04 15:46:35 +02:00
evgeny 2afb7268a1 Restore PM group route and verify messaging after invite JOIN 2026-10-04 15:46:14 +02:00
evgeny efcc9a1761 Schedule member sync when joining over an existing transport 2026-10-04 15:43:15 +02:00
evgeny c800d9253d Trace group connection and membership after opening a received invitation 2026-10-04 15:39:06 +02:00
evgeny 92b41ec300 Test wrapped message links and per-member invitation button hit targets 2026-10-04 15:38:10 +02:00
evgeny 8e25ffb392 Wait for member replication after JOIN and include desktop diagnostics 2026-10-04 15:24:06 +02:00
evgeny 570e637795 Verify desktop invitation clicks preserve drag selection 2026-10-04 15:12:26 +02:00
evgeny b9af72e71d Test PM invitation cancellation, commit errors and joining another group 2026-10-04 15:12:26 +02:00
evgeny f07a5b7a83 Keep invite hit testing in the message presenter and show link cursor 2026-10-04 15:10:02 +02:00
evgeny 149c397b7b Include desktop diagnostic macros for invitation actions 2026-10-04 15:08:16 +02:00
evgeny 3c3f3896f7 Handle message invitation links in Android channel and PM screens 2026-10-04 15:04:14 +02:00
evgeny 68103d0aca Make invite links clickable in Android text with inline animated emoji 2026-10-04 15:03:54 +02:00
evgeny 442a2a7b04 Complete Android invitation dialog imports and show share link lifetime 2026-10-04 15:03:53 +02:00
evgeny d13663eb23 Add Android PM and member invitation buttons with group picker 2026-10-04 15:02:42 +02:00
evgeny e5a87bd043 Track Android PM invitations and joining from message links in ViewModel 2026-10-04 15:02:27 +02:00
evgeny f841c8eb8a Localize PM invitation actions, lifetime and error messages 2026-10-04 15:00:45 +02:00
evgeny 81f8f6d4d0 Use asynchronous post API for invitation requests 2026-10-04 15:00:44 +02:00
evgeny 9bdfb93b50 Expose PM invitation operations and membership checks through JNI 2026-10-04 14:59:08 +02:00
evgeny ef62a80eb8 Filter desktop invitation targets by local membership 2026-10-04 14:59:08 +02:00
evgeny 55d9e79983 Expose read-only channel membership for invitation UI 2026-10-04 14:59:07 +02:00
evgeny fb21f9c1af Show invitation lifetime and correlate desktop join results by group 2026-10-04 14:57:12 +02:00
evgeny d369ff968d Wire desktop invitation sending and joining from message links 2026-10-04 14:57:12 +02:00
evgeny b7821121c3 Activate desktop invite links on clicks while preserving drag selection 2026-10-04 14:56:11 +02:00
evgeny 56fe1cab95 Render and hit-test wrapped invitation links in desktop messages 2026-10-04 14:56:10 +02:00
evgeny 01aa692a56 Add group invitation button to desktop PM header 2026-10-04 14:54:59 +02:00
evgeny 44e75e661e Forward member invitation actions to main window 2026-10-04 14:54:58 +02:00
evgeny fe23f4ca56 Add invitation action to desktop member rows 2026-10-04 14:54:58 +02:00
evgeny 6bc6d28e9e Add desktop group picker for PM invitations with ten minute notice 2026-10-04 14:53:59 +02:00
evgeny fb68e66ca4 Dispatch PM invitation results to desktop UI 2026-10-04 14:53:58 +02:00
evgeny 6f99ad3103 Add cancellable PM invitation operation with correlated results 2026-10-04 14:51:33 +02:00
evgeny 123b47c612 Improve Android VAD lifecycle, audio settings and diagnostics 2026-10-04 14:36:52 +02:00
evgeny 20a1211e09 Add GPLv3 licensing and bundle third-party notices 2026-10-04 14:18:18 +02:00
evgeny a97e8bcc1f docs: update file inventory and module header contracts
Refresh both AGENTS guides and clarify module purpose, usage, ownership, threading, return values and wire formats in headers. Remove the unused timeout_heap freed_count field and unimplemented getter.
2026-10-04 13:10:01 +02:00
evgeny c19eff67f6 android chat: refine message bubble colors and shadows 2026-10-03 14:22:21 +03:00
evgeny 5c74b7cd3e android radio: add plus and minus to volume PTT icon 2026-10-03 14:21:20 +03:00
evgeny 8358210241 docs: record Android volume PTT panel verification 2026-10-03 14:13:48 +03:00
evgeny de54c2d059 android radio: add volume PTT toggle to radio panel 2026-10-03 14:08:17 +03:00
evgeny 40e6bd36c3 android radio: release volume PTT on focus loss and option disable 2026-10-03 14:08:17 +03:00
evgeny 1805b3dd27 android radio: track independent manual PTT owners 2026-10-03 14:08:17 +03:00
evgeny 163621ddfa Document verified desktop radio panel and VAD controls 2026-10-03 13:34:50 +03:00
evgeny c1bec9aca5 Wait for queued radio packets and verify persistent VAD settings 2026-10-03 13:29:33 +03:00
evgeny 33f276a69e Cover radio panel shutdown and microphone recovery states 2026-10-03 13:19:45 +03:00
evgeny a2bafb61c7 Own pending radio settings in cancellable uasync tasks 2026-10-03 13:18:09 +03:00
evgeny 312c2dd386 Test desktop VAD panel through Qt buttons and real audio workers 2026-10-03 13:16:15 +03:00
evgeny 8820e9a3c9 Build desktop radio panel and retain audio recovery coverage 2026-10-03 13:13:28 +03:00
evgeny 625846fa33 Apply shared audio changes without resetting saved preferences 2026-10-03 13:13:28 +03:00
evgeny afbce0efeb Load radio settings after core startup and apply from dialog 2026-10-03 13:12:17 +03:00
evgeny 9f41415dc7 Expose radio VAD thresholds and independent compressor gains 2026-10-03 13:11:54 +03:00
evgeny d1e2220e54 Place radio controls above desktop chat messages 2026-10-03 13:10:38 +03:00
evgeny fa70093866 Add desktop radio panel with device menus and VAD switch 2026-10-03 13:09:38 +03:00
evgeny dcb07c9124 Add live desktop radio VAD settings and transmission state 2026-10-03 13:08:04 +03:00
evgeny ffd26c56b4 Reduce radio VAD prefetch to 600 milliseconds 2026-10-03 11:32:34 +03:00
evgeny 6985a2cf18 Document Android radio toolbar VAD control 2026-10-03 11:28:23 +03:00
evgeny 9ff1f5645f Move Android VAD activation to the radio toolbar 2026-10-03 11:18:04 +03:00
evgeny 099c9b7eac Record successful VAD validation and full test results 2026-10-03 01:53:03 +03:00
evgeny 13b5136b92 Document radio VAD compressor behavior and validation 2026-10-03 01:50:31 +03:00
evgeny c9131fff39 Ship deterministic speech fixture for VAD regressions 2026-10-03 01:48:37 +03:00
evgeny 50e276cb94 Include previous audio context in streaming Silero inference 2026-10-03 01:48:37 +03:00
evgeny 9c8f635e63 Test VAD compression, quiet speech and independent prefetch audio 2026-10-03 01:34:27 +03:00
evgeny cd57597975 Expose radio VAD gain limit in Android settings 2026-10-03 01:30:31 +03:00
evgeny cbee3da2c9 Add independent compressor branch before radio VAD 2026-10-03 01:30:31 +03:00
evgeny 389fca1de0 Expose compressor gain and register separate radio VAD limit 2026-10-03 01:27:42 +03:00
evgeny 1e9264735b Fix desktop hover and emoji playback; share Android chat background 2026-10-02 23:19:13 +03:00
evgeny 35648a19ce Avoid Windows poll macro collision in PTT hotkey manager 2026-10-02 17:32:46 +03:00
evgeny 23368a5bbe Add Android boot startup, lazy settings, emoji and DM calls
Add battery optimization controls and configurable boot startup. Keep message sounds in the application and render general settings lazily to avoid ANRs. Add animated emoji controls and live BGP availability for direct-message calls on Android and desktop.
2026-10-02 17:18:24 +03:00
evgeny 66afcc8625 Add extensible Russian and English interface languages on Android 2026-10-02 16:05:33 +03:00
evgeny df346fc097 Log standby retry transitions and await the actual wake phase 2026-10-02 12:04:34 +03:00
evgeny 7ec5f931bb Defer automatic retries until Android standby wakes 2026-10-02 11:56:44 +03:00
evgeny f12bab8676 Include concrete transport definitions for UP checks 2026-10-02 11:52:36 +03:00
evgeny f4b273d0be Cover UP-based chat peer selection and fallback transitions 2026-10-02 11:50:28 +03:00
evgeny 1d189195f9 Advertise desktop clients and log unknown automatic candidates 2026-10-02 11:47:24 +03:00
evgeny dc34faaada Route chat retries through automatic peer selection 2026-10-02 11:44:46 +03:00
evgeny a7632cfee1 Select chat auto peers by device class and transport UP 2026-10-02 11:43:10 +03:00
evgeny 1c499dc230 Classify chat supernodes independently of address type 2026-10-02 11:37:09 +03:00
evgeny 01bc6e4cf0 Опиши контракты аудиотракта и результаты проверок 2026-10-02 10:22:47 +03:00
evgeny bd082a26bf Раздели аудиопотоки и привяжи AEC к фактическому общему выходу 2026-10-02 10:22:34 +03:00
evgeny d7fb0c83f9 Fix bounds and unsigned decoding in ETCP packet dumps 2026-10-02 02:52:32 +03:00
evgeny ac45554439 Fix ETCP INIT collision scope and backpressure regression tests 2026-10-02 02:25:40 +03:00
evgeny 217e5795bf Раздели PCM-сессии и исправь частоту и перемотку звука 2026-10-02 02:00:50 +03:00
evgeny 40b974b29c Исправь потоковый AGC и применяй mute после AEC 2026-10-02 01:56:10 +03:00
evgeny bdcf8b5634 Сохрани накопленные исправления аудио, async и диагностики 2026-10-02 01:49:32 +03:00
evgeny b1e3193899 Document typed PM media, shared preparation and completed validation 2026-10-01 19:22:06 +03:00
evgeny 7ae56f03b3 Keep Android video metadata truthful and remove obsolete composer imports 2026-10-01 19:16:27 +03:00
evgeny 203ae61eda Share bounded thumbnail workers and keep PM downloads in DM transport 2026-10-01 19:12:25 +03:00
evgeny c863b80917 Validate Android voice streams and keep playback cancellation off UI waits 2026-10-01 19:09:07 +03:00
evgeny dd8041b30f Retain picker cache ownership on native PM rejection 2026-10-01 19:06:19 +03:00
evgeny fe9441d63b Acknowledge Android PM file ownership only after native enqueue 2026-10-01 19:06:18 +03:00
evgeny 05476fb102 Test Qt voice file validation and decoder cancellation 2026-10-01 18:56:57 +03:00
evgeny 6ccf71b20d Exercise separate conversations and codec format boundaries 2026-10-01 18:56:57 +03:00
evgeny 418329962d Test pinned preparation targets, worker ownership and typed offline media 2026-10-01 18:55:34 +03:00
evgeny f2ff3ee5ab Report preparation rejection and release abandoned owned sources 2026-10-01 18:53:08 +03:00
evgeny 3b0609fe76 Reject corrupt voice containers and remove unused synchronous playback 2026-10-01 18:51:44 +03:00
evgeny 8e108425ae Track Android video probing and clean rejected cache files 2026-10-01 18:50:32 +03:00
evgeny 20322e7ecb Show PM voice and video delivery status in both shared renderers 2026-10-01 18:49:59 +03:00
evgeny 5092bdf9fe Validate capture format and diagnose capture thread failures 2026-10-01 18:48:57 +03:00
evgeny be8dbcf25e Remove duplicate GUI voice encoding and keep shared worker codec 2026-10-01 18:48:09 +03:00
evgeny 72233d2365 Quiesce Android capture before detaching PCM and consume PM cache files 2026-10-01 18:41:17 +03:00
evgeny 79f0f2a07f Keep Android media preparation status scoped to its conversation 2026-10-01 18:41:17 +03:00
evgeny 225e11265f Connect Qt preparation notifications to the conversation view 2026-10-01 18:39:31 +03:00
evgeny 6da6471204 Apply task-scoped media preparation events to the shared Qt composer 2026-10-01 18:39:31 +03:00
evgeny e4a57970f0 Show preparation state for the current Qt conversation only 2026-10-01 18:39:31 +03:00
evgeny 55b21fdcda Forward pinned attachment preparation events to Qt 2026-10-01 18:37:49 +03:00
evgeny 51a820ac82 Track PM encryption preparation and clean cancelled source files 2026-10-01 18:37:23 +03:00
evgeny c900adbc69 Report pinned preparation results and clean abandoned media outputs 2026-10-01 18:36:59 +03:00
evgeny b1ee7857f7 Identify media preparation events by conversation and task UUID 2026-10-01 18:36:59 +03:00
evgeny 318d72708c Preserve voice autoplay ordering while decoding in a worker 2026-10-01 18:29:43 +03:00
evgeny 172cc3a649 Update shared Qt playback controls after background decoding 2026-10-01 18:29:07 +03:00
evgeny d4a27d1975 Decode voice files asynchronously before starting Qt playback 2026-10-01 18:27:44 +03:00
evgeny c77cb9bb0a Adopt decoded voice buffers without large copies on the Qt thread 2026-10-01 18:27:44 +03:00
evgeny add016894b Use bounded independent Android cache files for each attachment 2026-10-01 18:24:12 +03:00
evgeny fd3fc971fa Return Android video recording to its original channel or PM 2026-10-01 18:19:37 +03:00
evgeny fef800ef7a Use the same Android media interface for channels and PM 2026-10-01 18:19:12 +03:00
evgeny 1cd366c0e1 Share Android conversation composition attachments and message lists 2026-10-01 18:16:23 +03:00
evgeny dbec6e75e8 Pin Android recording targets and stop capture outside the main thread 2026-10-01 18:13:35 +03:00
evgeny 80b4e6f3e9 Normalize PM voice and video into the Android message model 2026-10-01 18:12:14 +03:00
evgeny 6185869c6d Use fixed conversation targets for Android media preparation 2026-10-01 18:11:54 +03:00
evgeny 038fd173c2 Detach Android recordings for shared background preparation 2026-10-01 18:01:45 +03:00
evgeny 14935378bb Check queued worker completion cancellation and attachment codec tests 2026-10-01 18:00:02 +03:00
evgeny 0dc2b0135a Test typed PM delivery and strict voice attachment metadata 2026-10-01 17:59:16 +03:00
evgeny c58b92ecd7 Render typed PM media using shared Qt message roles 2026-10-01 17:57:43 +03:00
evgeny a281165450 Keep channel download commands out of the shared message delegate 2026-10-01 17:56:29 +03:00
evgeny 4f76b4d765 Dispatch Qt attachments using the target captured by the composer 2026-10-01 17:54:48 +03:00
evgeny d1f03f2f80 Enable shared Qt voice and video composition for PM 2026-10-01 17:53:41 +03:00
evgeny 0d3f2952c1 Move Qt recording buffers to background preparation without copies 2026-10-01 17:52:38 +03:00
evgeny ba409427c6 Bound media worker concurrency and reject incomplete file copies 2026-10-01 17:51:09 +03:00
evgeny 1b3794e9f9 Include common attachment preparation in both core targets 2026-10-01 17:50:46 +03:00
evgeny 555b6fcf86 Prepare voice and video before dispatching to a fixed conversation 2026-10-01 17:49:52 +03:00
evgeny 1bd310c859 Detach recorder compressors while preserving capture settings 2026-10-01 17:47:39 +03:00
evgeny 20acf975d9 Return final video metadata from the preparation worker 2026-10-01 17:46:55 +03:00
evgeny 984b9e8123 Keep PM attachment kinds scoped to files voice and video 2026-10-01 17:43:53 +03:00
evgeny c7310e1fad Register shared voice encoding in core build targets 2026-10-01 17:43:10 +03:00
evgeny a5f90ec207 Share voice file encoding and final PCM metadata across clients 2026-10-01 17:42:44 +03:00
evgeny 72d1d3f582 Validate PM attachment metadata before committing messages 2026-10-01 17:41:19 +03:00
evgeny 7b8e2cd96c Transfer temporary source ownership before launching PM workers 2026-10-01 17:40:49 +03:00
evgeny c1185b62c1 Carry typed encrypted metadata with PM file transfers 2026-10-01 17:39:48 +03:00
evgeny 7357a63fdf Define bounded typed attachment metadata for PM and GUI 2026-10-01 17:38:25 +03:00
evgeny adff64e483 Deliver media completions without polling or timer failure joins 2026-10-01 17:36:43 +03:00
evgeny 00e890e0c3 Reserve worker completions before starting background tasks 2026-10-01 17:36:12 +03:00
evgeny 142eefaf86 Record completed PM media integration and validation results 2026-10-01 17:00:55 +03:00
evgeny 7e780bb6a7 Document PM file custody, worker ownership and client integration 2026-10-01 16:44:38 +03:00
evgeny ef5cd63d9f Set injected control packet lengths so replay and quota checks execute 2026-10-01 16:40:53 +03:00
evgeny 7bd3e0d4de Test PM media rollback, quota, snapshots and transfer cancellation 2026-10-01 16:35:55 +03:00
evgeny 18ee21cf93 Allow receipt-authorized custody cleanup after role revocation 2026-10-01 16:34:00 +03:00
evgeny 934f1ccd1f Use the existing diagnostic macros for desktop PM errors 2026-10-01 16:32:14 +03:00
evgeny a90274f24c Test event-loop heartbeat during sustained PM file encryption 2026-10-01 16:31:51 +03:00
evgeny dc1110af4d Add Android PM attachment selection, saving and delivery labels 2026-10-01 16:29:12 +03:00
evgeny 1457275139 Update Android PM screens from asynchronous core events 2026-10-01 16:27:58 +03:00
evgeny 52e38ff5d6 Parse PM snapshots and delivery states in the Android repository 2026-10-01 16:27:58 +03:00
evgeny 8403697013 Post Android PM reads and file sends to the core event loop 2026-10-01 16:27:01 +03:00
evgeny d9eee4e520 Bound and safely serialize PM conversation snapshots 2026-10-01 16:25:52 +03:00
evgeny e562896d63 Define asynchronous conversation snapshots for PM clients 2026-10-01 16:25:52 +03:00
evgeny 7fee3ec551 Render asynchronous PM history and submit desktop file sends 2026-10-01 16:24:09 +03:00
evgeny 1ceb09062f Show PM file delivery state without invoking group downloads 2026-10-01 16:22:54 +03:00
evgeny 570f3dfab3 Enable original file attachments in the desktop PM composer 2026-10-01 16:22:32 +03:00
evgeny 4cabbc32f5 Fit file chunks within the signed router packet limit 2026-10-01 16:22:07 +03:00
evgeny 3d6f9c1be4 Sign media test fixtures with the derived Ed25519 seeds 2026-10-01 16:14:39 +03:00
evgeny 76497481f7 Test direct and offline DM media with separate supernode and storage nodes 2026-10-01 16:04:35 +03:00
evgeny 139356bd18 Deliver DM history snapshots asynchronously as JSON events 2026-10-01 16:00:39 +03:00
evgeny 1cdead18de Expose bounded DM history snapshots with text and media delivery state 2026-10-01 15:59:38 +03:00
evgeny b47918fad5 Keep media publication and durable deletion off the event loop 2026-10-01 15:57:30 +03:00
evgeny 55c9d79a01 Integrate atomic media registration and orderly transfer/worker shutdown 2026-10-01 15:53:53 +03:00
evgeny d7a12b24bf Coordinate offline DM media custody and durable deletion on supernodes 2026-10-01 15:52:05 +03:00
evgeny 41fc5902be Implement durable DM downloads, media-node custody, quota and expiry 2026-10-01 15:47:05 +03:00
evgeny e47c7fb2ac Allow file owners to revoke active transfers on custody expiry or deletion 2026-10-01 15:42:54 +03:00
evgeny 84c148acff Prepare and publish target-encrypted DM files with exact media receipts 2026-10-01 15:42:02 +03:00
evgeny d559cbf473 Add configurable seven-day DM custody TTL and reserved storage quota 2026-10-01 15:36:31 +03:00
evgeny 5e9a9059c8 Bind signed file descriptors to atomic DM enqueue and receive 2026-10-01 15:28:40 +03:00
evgeny 27fa3a4812 Define independent DM media metadata, receipts and custody contracts 2026-10-01 15:27:44 +03:00
evgeny 3d0ab35efe Register file transfer and DM media services in the common core 2026-10-01 15:22:10 +03:00
evgeny f39ba840b8 Add bounded signed file transfers with per-operation CM ownership 2026-10-01 15:21:44 +03:00
evgeny 6c86e380a8 Record DM stage validation and pending media delivery work 2026-10-01 15:06:08 +03:00
evgeny c63343cf2b Stop DM test event loops promptly on scenario failure 2026-10-01 14:51:37 +03:00
evgeny bd550159f0 Verify DM queues drain beyond one delivery batch after restart 2026-10-01 14:48:37 +03:00
evgeny 43c89ca1ed Document implemented DM guarantees and remaining media integration 2026-10-01 14:46:24 +03:00
evgeny 1740bec94f Test mailbox admission, exact deletion and late PUT replay 2026-10-01 14:43:50 +03:00
evgeny 0e0f611d3c Check atomic DM enqueue rollback and explain sequence conflicts 2026-10-01 14:41:33 +03:00
evgeny bd05ab6d3a Verify DM media record boundaries and corrupted artifacts 2026-10-01 14:35:43 +03:00
evgeny 467d2e7605 Prepare DM media as authenticated records using target key 2026-10-01 14:33:45 +03:00
evgeny 10de4f1c71 Commit DM activity timestamps together with message state 2026-10-01 14:28:47 +03:00
evgeny 794d7b70f3 Authorize DM custody by signed group role instead of NAT type 2026-10-01 14:27:54 +03:00
evgeny e6c78c17b7 Keep DM test diagnostics focused on delivery state 2026-10-01 14:24:28 +03:00
evgeny 3cdb3e6580 Create DM router streams before checking queue capacity 2026-10-01 14:24:18 +03:00
evgeny febc3419b0 Exercise DM reordering, rollback and signed acknowledgments 2026-10-01 14:22:46 +03:00
evgeny 937ef9fcef Test CCM limits and offline DM custody across restart 2026-10-01 14:20:19 +03:00
evgeny 5800902a42 Deliver offline DM through durable supernode custody 2026-10-01 14:18:50 +03:00
evgeny cc072cceb2 Persist DM outbox and verify exact delivery receipts 2026-10-01 14:14:46 +03:00
evgeny 67bbf80769 Fix DM CCM length setup and separate media nonces 2026-10-01 14:04:25 +03:00
evgeny ce5f5bb7d0 Improve Android onboarding, member UI and PTT permissions 2026-10-01 13:55:28 +03:00
evgeny 577bfb4e6f Record independent audio startup checks and phone updates 2026-10-01 03:05:00 +03:00
evgeny fe1d29f007 Check refill below the 60 ms reserve including SoundTouch 2026-10-01 02:59:50 +03:00
evgeny fbf50b093d Document independent call audio startup and delivery reserve 2026-10-01 02:58:45 +03:00
evgeny 5b0262d53f Diagnose refill expectation with the corrected reserve 2026-10-01 02:57:18 +03:00
evgeny 4a2efe21c7 Start Android capture and playback independently 2026-10-01 02:56:29 +03:00
evgeny 7d9f13b8bc Test startup backlog independently of delivery jitter 2026-10-01 02:51:04 +03:00
evgeny 50e3db81ea Separate playback backlog from adaptive call reserve 2026-10-01 02:49:35 +03:00
evgeny d8745fd303 Measure call jitter from media delivery timestamps 2026-10-01 02:48:53 +03:00
evgeny bc797550d9 docs: record SM startup timings after phone update 2026-10-01 02:25:49 +03:00
evgeny 5ebab7072c docs: record call startup validation results 2026-10-01 02:19:58 +03:00
evgeny 9ff4e68246 docs: describe call audio startup and loss tone gating 2026-10-01 02:14:15 +03:00
evgeny 00666499fe android: start call capture before playback setup 2026-10-01 02:12:44 +03:00
evgeny 5487bc8c20 call: suppress loss tone until first received PCM 2026-10-01 02:08:17 +03:00
evgeny a3f6b6e86e docs: outline simple Android call startup improvements 2026-10-01 02:00:56 +03:00
evgeny 6f66df61f7 docs: record false audio loss tone during call startup 2026-10-01 01:58:20 +03:00
evgeny 72b5a9887f chatgui: measure duplex audio stalls and record SM call evidence 2026-10-01 01:36:34 +03:00
evgeny 076cc3c617 docs: record full recovery checks and root socket test 2026-10-01 01:19:37 +03:00
evgeny 91a69b939c docs: record conn_mgr recovery validation and check timeout limitation 2026-10-01 01:15:15 +03:00
evgeny 969c085085 tests: resend withdrawn relay advertisements during recovery 2026-10-01 01:09:15 +03:00
evgeny 426fc2f4e8 conn_mgr: verify route loss and document handle lifetime recovery 2026-10-01 01:06:56 +03:00
evgeny 464575ef44 conn_mgr: exercise persistent retries with valid signed node updates 2026-10-01 01:01:49 +03:00
evgeny a65ef30d78 conn_mgr: resume recovery when local sockets change 2026-10-01 00:51:17 +03:00
evgeny 8f5f2b089c conn_mgr: keep demand alive across bounded recovery attempts 2026-10-01 00:50:44 +03:00
evgeny 111432aa64 conn_mgr: race connection probes and report call path with correct RTT 2026-10-01 00:42:47 +03:00
evgeny 1c51df039f Fix call gap tone to follow 500ms of missing jitter PCM 2026-09-30 21:14:37 +03:00
evgeny 9e3a417059 Synchronize standby transitions and immediate keepalive phase announcements 2026-09-30 20:42:40 +03:00
evgeny e914a1bdc1 Improve Android member details contrast 2026-09-30 20:13:25 +03:00
evgeny b36c685cfa Show ongoing Android calls on the lock screen 2026-09-30 19:42:12 +03:00
evgeny 3c5c9604b3 Keep Android calls active independently of screen and UI 2026-09-30 19:12:04 +03:00
evgeny fb37ca747a 1 2026-09-30 17:37:13 +03:00
evgeny 2d21c53b4b Improve call buffering, CM handle lifecycle and radio PTT controls 2026-09-30 17:31:53 +03:00
evgeny 752c1f140c Add unified Android dark theme and improve UI contrast 2026-09-30 13:41:45 +03:00
evgeny db3cacd33e Rename Android app to vibechat 2026-09-30 13:10:09 +03:00
evgeny 7ebc282eb2 Prioritize supernodes in invites and update chat background and ringtone 2026-09-30 12:56:59 +03:00
evgeny 0d44ada922 Improve Android radio capture lifecycle, VAD and PTT controls 2026-09-30 12:25:42 +03:00
evgeny 52ffb91101 Fix TCP proxy use-after-free during synchronous close 2026-09-30 10:43:02 +03:00
evgeny 745ec3dbd2 android radio: preserve output route on reconfigure, link input/output settings 2026-09-29 22:35:08 +03:00
evgeny 15958a078e android: self-managed Telecom ConnectionService for call audio routing 2026-09-29 21:26:24 +03:00
evgeny 61bf235ef4 radio: PTT double-tap latch + single-tap off (in-chat & overlay); compressor initial gain = mid-range 2026-09-29 20:00:28 +03:00
evgeny 556b0bc7b7 call/radio: mic AGC compressor + selectable input device; proximity lock 2026-09-29 19:34:23 +03:00
evgeny f12f61d7ee call: add SpeexDSP AEC (acoustic echo cancellation) for desktop + Android 2026-09-29 17:01:30 +03:00
evgeny 1176411b79 radio: Silero VAD + auto-PTT; chatgui/android: app icon and background 2026-09-29 16:19:25 +03:00
evgeny 74ca98b38f proxy: rename pcb guard, dedupe abort; tasks: FIN_WAIT_2 leak 2026-09-29 13:52:35 +03:00
evgeny 961a234d7d proxy: detach lwIP pcb on local close, guard abort against freed pcb
При half-close (exit закрылся первым, браузер держит соединение) pcb уходил в
TIME_WAIT, а conn_finish ждал flow.fin_sent (доставку FIN в exit) — при backpressure
это не наступало, pc->pcb оставался висячим. Таймер TIME_WAIT освобождал pcb без
err_cb, и CLOSE_ALL давал double free. Теперь pcb отсоединяется по завершении
локальной стороны, а tcp_abort/tcp_close защищены проверкой memory_pool_is_freed.
2026-09-29 13:37:00 +03:00
evgeny a73ae13df4 lwip/proxy: trace PCB lifetime in debug category, drop old noisy debug 2026-09-29 13:18:18 +03:00
evgeny d8cbe2e589 Add proxy bug list and lightsout game (desktop + Android) 2026-09-29 12:19:23 +03:00
evgeny e1946b208d Preserve proxy TCP streams across connect, backpressure and FIN 2026-09-29 04:00:34 +03:00
evgeny 09bc8c35c5 Release TUN proxy connections when lwIP aborts their PCB 2026-09-29 03:59:30 +03:00
evgeny f19ff11b36 Scope TCP proxy streams and restart messages to their peer 2026-09-29 03:58:53 +03:00
evgeny 268243feeb Isolate datagram proxy state and replies between instances and peers 2026-09-29 03:58:14 +03:00
evgeny 4be1e62251 Parse IPv4 options and reject malformed TUN proxy packets 2026-09-29 03:57:37 +03:00
evgeny 10b66e2ad0 Validate SOCKS5 authentication and destination addresses 2026-09-29 03:57:21 +03:00
evgeny 7a41fcf512 Notify TCP writers when the final synchronous send drains 2026-09-29 03:57:15 +03:00
evgeny 518df33b0e Fix UDP and ICMP packet construction at the TUN boundary 2026-09-29 03:56:55 +03:00
evgeny fdec5b65c5 Add independent radio compressor and Android audio controls 2026-09-29 03:37:47 +03:00
evgeny ce1f23fe46 Radio: stereo capture/playback with mono fallback; CAMCORDER source; bump RADIO_MAX_OPUS
- stereo capture: Android AudioRecord stereo (CAMCORDER source for stereo,
  voice sources fall back to CAMCORDER) + desktop separate miniaudio
  capture/playback devices (no asymmetric duplex)
- Opus stereo encode/decode, voice_jitter stereo (per-channel frame_size,
  slot-based SoundTouch)
- radio_audio_start takes explicit capture_channels (stereo->mono fallback)
- RADIO_MAX_OPUS 256->512 (128kbps stereo frames up to 320B)
- radio_capture_stereo setting + desktop radio settings UI (opus mode/bitrate,
  capture stereo)
- radio_send_to send stats logging (etcp_send ok/fail per second)
2026-09-29 02:31:41 +03:00
evgeny 331970a121 Radio: Opus mode/bitrate + mic source + PTT release tail; drop online status from member JSON 2026-09-29 00:40:10 +03:00
evgeny e3caf15f32 Guard routing loops and reconcile blocked transit against current paths
Track visited nodes outside the signed body for all routed packet types. Recheck queued transit routes without losing FIFO priority, reject unknown-group transit, and suppress BGP announcements caused only by RTT jitter.

Document routing rules and wire format. Validate graph churn, REINIT, encrypted transit, malformed paths, loop drops and queue cleanup; full suite: 106 passed, 1 skipped, plus proxy integration and sanitizer checks.
2026-09-28 15:36:47 +03:00
evgeny fa9e102271 Preserve config string terminator when preparing key updates 2026-09-28 15:16:57 +03:00
evgeny 39ce249361 Prune unconfirmed BGP paths and restart stalled exchanges 2026-09-28 14:58:13 +03:00
evgeny b76e6553bc Reconcile BGP paths and advertise selected routes per neighbor 2026-09-28 14:37:44 +03:00
evgeny 546e0c185d Fix WITHDRAW removing nodes with surviving paths 2026-09-28 14:20:55 +03:00
evgeny 4503bdfa7e diagnostics: explain and rate-limit rejected ETCP session data 2026-09-28 13:16:39 +03:00
evgeny c63e93715f fix: accept invite public keys with a leading zero byte 2026-09-28 12:26:13 +03:00
evgeny 904a9fbda1 docs: refresh development guides for current architecture 2026-09-28 12:10:39 +03:00
evgeny 01fcefdec5 docs: clarify core, group and chat header contracts 2026-09-28 12:01:08 +03:00
evgeny 72fee9e245 Separate core, UTUN and chat lifecycles with owned asynchronous work 2026-09-28 11:39:08 +03:00
evgeny 5838e63cde Use shared group requests for config and chat connection planners 2026-09-28 11:07:25 +03:00
evgeny 0756a6e020 Serialize group topology lazily through a cancellable backpressure sender 2026-09-28 02:45:00 +03:00
evgeny 792776a1f6 Negotiate group sessions and scope topology messages to peer epochs 2026-09-28 02:15:54 +03:00
evgeny 52ef7a4b3c Own recovery attempts in group sessions and require restored routes 2026-09-27 23:06:48 +03:00
evgeny 66c59501fc Track topology exchange readiness per group and peer 2026-09-27 22:14:03 +03:00
evgeny bce17d9cfc Route UTUN configuration and group ownership through NCD 2026-09-27 21:59:32 +03:00
evgeny 9745a987ac Define join contract and require committed CHAT membership for BGP 2026-09-27 20:34:24 +03:00
evgeny 1a8072e9b2 Release group NCD ownership when destroying peers 2026-09-27 20:08:17 +03:00
evgeny 26e6c05313 Apply fresh BGP addresses to shared NCD connections 2026-09-27 19:18:40 +03:00
evgeny ec51b2d61f Version signed node snapshots with persistent timestamps 2026-09-27 19:11:11 +03:00
evgeny 7374d1648c Support 8 KiB member owner tags without signature or serialization truncation 2026-09-27 17:12:13 +03:00
evgeny de714f5023 Add bounded Merkle pull lifecycle and terminal error handoff 2026-09-27 16:17:04 +03:00
evgeny 3e25bcef02 Refactor Merkle sync into bounded bidirectional rounds with atomic member updates 2026-09-27 14:44:39 +03:00
evgeny 1b92b4885b Restrict dynamic auto socket test to Linux 2026-09-27 12:48:40 +03:00
evgeny 10d3ecfda4 Record final root transport and full suite validation 2026-09-27 12:19:52 +03:00
evgeny 03f71fd94e Bound ETCP receive window and fix timestamp and allocator UB 2026-09-27 12:16:15 +03:00
evgeny 59f4802904 Fix autosocket ownership and exercise interface churn under load 2026-09-27 11:57:29 +03:00
evgeny 3131dcbb7c Fix ETCP session recovery and router lifecycle; confirm chat invites before publishing 2026-09-27 02:51:47 +03:00
evgeny 018c8e795d android: фикс UAF AudioTrack при переключении группы рации (start → releaseLocked) 2026-09-26 19:18:42 +03:00
evgeny 0209bcf5d3 android: рация — единый режим per-канал, не гаснет при выходе/заходе в группу 2026-09-26 19:12:07 +03:00
evgeny 44d4265084 ll_queue: queue_waiter_cancel отменяет отложенный call_soon при internal==NULL (фикс UAF waiter_defer) 2026-09-26 18:58:27 +03:00
evgeny f6e6e2c73f stcp: write-error закрывает conn отложенно (фикс UAF keepalive/etcp_tcp_send)
Синхронный send-путь (stcp_link_send → queue_data_put → tx_queue_cb →
flush_pending → try_send) при ошибке сокета вызывал stcp_conn_do_close →
on_close → tcp_link_close_cb → etcp_link_close внутри стека вызывающего,
освобождая ETCP_LINK под keepalive_timer_cb/etcp_tcp_send (use-after-free,
SIGSEGV в keepalive_timer_cb:210).

Теперь write-error планирует отложенный close (uasync_call_soon) с отменой
handle в stcp_conn_do_close; первый err сохраняется; flush_pending не работает
вне STCP_STATE_DATA. Мёртвый hook on_write_error удалён.
2026-09-26 16:42:51 +03:00
evgeny 8aaac45020 ll_queue: отложенный первый запуск автозабора (callback_defer) + тест
queue_set_callback_defer(q, 1) переносит первый запуск callback из
queue_data_put* в uasync_call_soon (очистка стека производителя).
Повторные запуски (queue_resume_callback) и так всегда deferred.
2026-09-26 16:42:46 +03:00
evgeny cc2d2b5f78 etcp: фикс UAF teardown (двойное закрытие линка) + вытеснение down-линка при коллизии адреса
- tcp_link_close_cb (серверная ветка): убрать преждевременный огонь link_status/on_link_down,
  etcp_link_close сам снимает линк из списка и стреляет коллбэки в безопасном порядке
  (устраняет двойное закрытие линка — UAF из callring 45502)
- etcp_connection_close: при callbacks_running откладывать закрытие через uasync_call_soon
  вместо *(int*)0=0
- callbacks_running: uint8_t-флаг -> int-счётчик вложенности (++/--)
- etcp_fire_conn_status / etcp_fire_link_status_cbk: поднимать callbacks_running вокруг огня
- insert_link_queue: при коллизии адреса с чужим conn — ERROR при одинаковом pubkey,
  отказ при up-линке, вытеснение (etcp_link_close) при down-линке

Попутно: доки/комментарии в etcp_router, ACK-интервал 100мс->10мс (ROUTER_ACK_INTERVAL_TB).
2026-09-26 13:40:33 +03:00
evgeny 265421eb96 tun proxy: фикс TCP-суммы (нечётный pbuf), FIN до дренажа to_lwip, tcp_bind/rexmit_fast/active_pcbs_changed + нагрузочный burst-тест 2026-09-25 23:36:45 +03:00
evgeny a20d73d2be proxy/tun: добавить DEBUG-логи диагностики застревания keep-alive (lwIP IN/OUT/RECVED/RTO/PERSIST + per-conn DIAG) 2026-09-25 22:12:47 +03:00
evgeny 4353daf913 freebsd: уникальный dst-адрес per-interface (tunN -> 192.0.2.(N+1)) 2026-09-25 20:16:39 +03:00
evgeny 3a4daf6e77 etcp: строгая последовательность коллбэков при закрытии (NEW→UP↔DOWN→DELETE)
- close: финальный per-connection DOWN только если был UP, до state=2
- etcp_cbk_fire / etcp_fire_conn_status / etcp_link_ready_callback / etcp_on_up: guard state==2
- документация контракта в etcp_api.h / etcp.h
2026-09-25 19:13:38 +03:00
evgeny ab5d1c5f91 topo_group: диагностика senders_list (new_conn/remove_conn) для локализации UAF
- new_conn: DEBUG_INFO ADD с conn/peer/state/ch
- remove_conn: state в enter-логе, детали в !found_in_list WARN, REMOVED-лог
2026-09-25 18:18:39 +03:00
evgeny 08e8b2f1cc route_connectivity: фикс UAF при удалении узла с влётными пробами; отмена TCP-пингов при teardown
- topo_nodeq_remove_node: единый хелпер удаления nq (cancel проб + free paths/subnets + remove + free), заменяет все free-сайты
- route_connectivity_cancel_all: итерация по всем группам + зануление ctx->nq + отмена standby-defer
- etcp_send_tcp_ping: out_cli — хендл stcp_client для досрочной отмены; conn_probe_ctx.tcp_cli
- conn_mgr: cand_tcp_pings[] — отмена влётных candidate TCP-пингов в conn_mgr_destroy
2026-09-25 16:01:19 +03:00
evgeny 3f7b4351cd stcp: фикс UAF log_dump, дренаж очередей при закрытии, защита pre-closed серверной ветки, логирование тихих сбросов rx 2026-09-25 13:49:43 +03:00
evgeny ceaf466b1c chatgui-android: входящий звонок поверх блокировки (inline-оверлей) + вибрация всегда кроме silent 2026-09-24 12:08:49 +03:00
evgeny fb4343fca6 transport: reality-релей idle-timeout (конфиг, дефолт 5с) + warn при >64 релеях; убрать лимит FD_SETSIZE; проверка socket_id в stcp_server 2026-09-24 12:08:45 +03:00
evgeny cc269e810c Звонки: надёжность отмены (INVITE-кодограмма + watchdog) и вибрация входящего по ringer-режиму 2026-09-24 10:15:19 +03:00
evgeny b90dc752d2 call: две фазы исходящего вызова — индикация + разные гудки (desktop/Android) 2026-09-23 19:16:53 +03:00
evgeny 7198154106 chatgui: клик по медиа с отсутствующим файлом — сброс пометки и перекачка 2026-09-22 21:59:59 +03:00
evgeny d237dfec7c diag: кольцевой трейс вызовов teardown + дамп при SIGSEGV (размотка UAF link close) 2026-09-22 20:52:02 +03:00
evgeny 4f29839de5 chat: инвайтер шлёт CONNECT_RESULT(0) после приёма джойнера
- chat_join_process_request: постить CHAT_EVT_CONNECT_RESULT(result=0) в GUI инвайтера
  (иначе диалог «Пригласить в канал» висел на «ожидание ответа»)
- cs_handle_join_request: снять pending_invite_* и погасить invite_send_timer после join
2026-09-22 18:26:44 +03:00
evgeny b46fd599fa chat: push-invite join key + запрет флагов на плейсхолдере
- CHANNEL_INVITE теперь несёт join_key (регистрируется инвайтером локально),
  джойнер шлёт JOIN_INFO_REQ с валидным ключом — чинит автоjoin chatserver-узлов
- ask-путь сохраняет join_key для chat_sync_accept_invite
- chat_member_tags_commit отвергает установку флагов на source!=0 (плейсхолдер)
- member_sync_apply_record: defensive ERROR при adm_tags на плейсхолдере
2026-09-22 17:58:50 +03:00
evgeny 0e625da109 call: ретрансмит INVITE каждые 2с + fail-fast при отсутствии маршрута (6с) 2026-09-22 16:06:52 +03:00
evgeny 93becd36e6 keepalive: TCP-линки без ретраев/ACK; не пинговать спящих пиров, bg-ping цикл ≤ 1/мин 2026-09-22 03:47:50 +03:00
evgeny a3e890b711 keepalive: раздельный sleep-код (announce+ACK-ретраи в окне, dead-link) + без flagless в спячке 2026-09-22 03:29:42 +03:00
evgeny a3df1720b4 keepalive: симметричный sleep-протокол (без is_server) + отдельный ACK-бит 2026-09-22 02:41:15 +03:00
evgeny 331c7849f0 keepalive: убрать периодический keepalive в standby (обе стороны молчат, только фазовые анонсы + один ack) 2026-09-22 02:19:28 +03:00
evgeny 945c6a82b0 keepalive: гвард нулевого тайминга фазы (busy-loop) + разделение echo/announce на сервере 2026-09-22 01:35:25 +03:00
evgeny cc0dcb071e chat: UI настройки звука канала (Android toggle + JNI, desktop через C API) + trampoline 2026-09-22 01:25:55 +03:00
evgeny 3d9c79e752 db_sync: троттлинг push к спящему пиру в тихом чате 2026-09-22 01:21:51 +03:00
evgeny b39b85db13 chat: троттлинг по фазе спячки (member_sync send-only, db_sync sound-aware) + настройка звука 2026-09-22 01:20:32 +03:00
evgeny 9f89fd0f7a transport: keepalive duty-cycle тайминг (active_remaining+sleep_duration) + серверная фаза троттлинга 2026-09-22 01:20:26 +03:00
evgeny 0a1ba79d6f chat: member_sync per-peer throttling on peer sleep (cancel_peer + recv/start gating) 2026-09-22 00:42:24 +03:00
evgeny e4e9fca243 transport: per-peer sleep callback (peer_sleep_cbk) fired from keepalive protocol 2026-09-22 00:40:32 +03:00
evgeny 5628138d16 etcp: keepalive sleep-протокол на флагах (KA_FLAG_SLEEP + sleep_time, announce-retry, ack/echo) 2026-09-21 23:30:39 +03:00
evgeny 8a9d8d0097 fix: утечки памяти в router-сервисах и при shutdown
- conn_mgr_router_recv_handler / md_etcp_recv не освобождали entry (рантайм-утечка на каждое сообщение)
- reality_relay: registry + shutdown hook (отложенный free не отрабатывал при остановке)
- etcp_router: uasync_drain_immediate после destroy (router_close_finalize)
- мелкие callback-списки: activity_cbks, node_cbks, props_cbks/apply_cbks
2026-09-21 21:55:11 +03:00
evgeny 2f3001458f android: standby keepalive sync + rx logging during sleep 2026-09-21 21:17:35 +03:00
evgeny 845af9200d Stop call ring sound immediately on accept 2026-09-21 19:41:21 +03:00
evgeny 328d36376c chat: пишем local_attrs атомарно при вставке своего медиа (гонка с MSG_RECEIVED) 2026-09-21 19:36:07 +03:00
evgeny 6e2a2f0011 media_download: сброс таймера простоя при CONN→REQ + правки диагностики
- md_dl_conn_cb: обнулять last_progress_tb при переходе CONN→REQ, иначе время
  установки indirect-соединения (~2с) засчитывается как простой блока и
  вызывал преждевременный фейловер с держателя, реально имеющего блок
- STALL-лог: печатать миллисекунды корректно (значение в единицах 0.1мс /10)
- media_index: INSERT OR IGNORE — повторная регистрация блока как servable
  больше не шумит как ERROR (UNIQUE constraint)
2026-09-21 19:16:27 +03:00
evgeny 9793733cd5 chatgui: диагностика воспроизведения голосовых сообщений (Windows)
- sound_manager: ma_engine_init/playRawPcm логируют через DEBUG_* (qWarning/qDebug терялись в GUI-приложении без консоли); детальный результат старта PCM (rc/is_playing/cursor)
- main: ранняя инициализация лога в GUI-потоке до SoundManager::init, чтобы диагностика инициализации попала в файл
- messagedelegate: лог клика по Play/timeline (filePath/dlState/существует ли файл)
- voiceplayback: лог заголовка opus (sr/ch/frameSamples)

Попутные правки:
- u_async: фикс двойного close wakeup_pipe (eventfd/Windows)
- chat_core: NULL-guard в get_db/is_initialized
- android: sqlite открывается в utun_instance_init, cleanup stale-потока без утечки fd
- android SettingsScreen: компактная раскладка имени интерфейса
2026-09-21 18:59:04 +03:00
evgeny 19dc076528 chatgui: инициализация call/dm/media backfill при старте узла (fix звонков) 2026-09-21 17:20:41 +03:00
evgeny 6a0373ee73 call: диагностика ставок TX/RX и детект сталла аудио-девайса с хард-ресинком 2026-09-21 16:54:14 +03:00
evgeny 570b421ba0 conn_mgr: parallel reverse+indirect, retransmit, and call teardown fix
- call_on_conn_status: only end call when its own data conn drops
  (INDIRECT call was killed by unrelated topo_group_connect conn DELETE)
- conn_mgr: run REVERSE and INDIRECT in parallel after DIRECT fails;
  reverse is preferred (indirect defers via indirect_ready until reverse
  resolves). REVERSE timeout 15s -> 3s.
- retransmit DIRECT_REQ / EXCHANGE_REQ every 1s (idempotent, same request_id)
  to survive packet loss (router RST dropping stale-channel requests)
- replace main.phase with reverse_active/indirect_active/indirect_ready flags
- add diagnostics to trace the parallel flow
2026-09-21 15:22:16 +03:00
evgeny ee54bd52b3 conn_mgr: fix reverse-phase timer leak causing use-after-free crash
cm_ncd_callback re-entered cm_start_phase_reverse on every NCD timeout
during REVERSE phase (shared NCD revived by other modules), leaking reverse
timers: only the last one was tracked in entry->main.timer, so cm_entry_cleanup
cancelled only that one and the earlier timers fired on the freed entry.

- ignore repeated NCD timeouts while already in REVERSE (phase==2)
- cancel entry->main.timer before overwriting in reverse/indirect phases
- remove entry from reverse_pending in cm_entry_cleanup
2026-09-21 13:57:32 +03:00
evgeny e885fe30f5 chatgui: remove universal black background from video window (fix black boxes around controls) 2026-09-21 12:50:06 +03:00
evgeny cd0757e272 chatgui: declare metatype for shared_ptr<vector<int16_t>> (Qt5 build fix) 2026-09-21 12:42:21 +03:00
evgeny f5fece4959 chatgui: fix video playback on Windows (metatype registration + swscale YUVJ range) 2026-09-21 12:39:18 +03:00
evgeny 01987a75d0 chatgui: verify FFmpeg DLL deployment + fix dependency resolution order 2026-09-21 11:52:21 +03:00
evgeny 9d4538935d chatgui: restore FFmpeg build script (build_ffmpeg.sh + .gitignore)
Скрипт был случайно удалён в d773f172 вместе с .gitignore/.opencode.
Без него на Windows не собирается ffmpeg/ffmpeg_build/install -> HAVE_FFMPEG
не определяется -> воспроизведение и транскодирование видео отключены.
2026-09-21 11:29:47 +03:00
evgeny 6ee9bad17d chat: defer media auto-download to per-channel backfill after sync
- db_sync insert-cb gets initial_sync flag (SEND_DATA=1, PUSH/local=0)
- on_msg_inserted skips media download during initial sync
- new chat_media_autodownload_backfill_channel (newest-first) triggered
  on SYNC_DONE per channel (2s debounce)
2026-09-21 02:07:24 +03:00
evgeny a5047c29f7 chatgui: always deploy non-Qt DLLs (FFmpeg, mingw-runtime) next to vibechat.exe 2026-09-21 00:58:56 +03:00
evgeny 2f1545de38 chatgui: fix Qt5 build — QMouseEvent/QWheelEvent position() -> localPos()/posF() 2026-09-21 00:51:48 +03:00
evgeny de850db548 chat: remove join_password check from per-channel JOIN_INFO_REQ (server-link only) 2026-09-20 22:23:42 +03:00
evgeny 39a1da4c28 chat: fix use-after-free in invite_candidates trampoline + accept JOIN_INFO_RESP/READY/ERROR for unknown channels 2026-09-20 22:03:31 +03:00
evgeny d1432b7d19 tests: fix Windows build — SKIP fork-based e2e, cross-platform mkdtemp/setenv 2026-09-20 20:21:50 +03:00
evgeny a7a3666d85 radio: AGC release-rate (без кликов), jitter dead-zone, TX/RX-статистика, FGS-гонка и кэш настроек 2026-09-20 20:07:48 +03:00
evgeny ba1c2d85d3 reality_relay: async DNS вместо getaddrinfo + AGC-компрессор по умолчанию (-12 dBFS) 2026-09-20 15:28:46 +03:00
evgeny 738cfe7835 radio: адаптивный джиттер-буфер (pre-roll, симметричный темп, reorder) + AGC-компрессор микрофона
- voice_jitter: vj_create_cfg (target_ms/min_tempo/max_tempo/pre_roll), pre-roll
  с таймаутом, vj_end для дренажа остатка, глубина учитывает внутренний буфер SoundTouch
- radio_audio: reorder по seq (mesh, out-of-order через соседей), force-flush pending
  по таймауту и FIN, компрессор микрофона (AGC, конфиг [chatserver]), статистика буфера
- audio_compressor: clear_output для потокового слива без потери gain_smoothed
- chatgui messagelist: fromUtf8 для emoji-строк
- тесты: pre-roll/симметричный темп, reorder, late-drop
2026-09-20 14:39:25 +03:00
evgeny 27e66f1092 log: move socket diagnostics SYS->SOCKET and conn lifecycle ETCP->CONNECTION (avoid poll() flood) 2026-09-20 01:51:40 +03:00
evgeny 1bde2eca35 diag: log conn add/remove/free pointers to pinpoint BGP senders_list UAF 2026-09-20 01:42:05 +03:00
evgeny 16237b0df8 etcp_send: fix contract (caller owns entry on error) + fix 7 leak sites 2026-09-20 01:35:30 +03:00
evgeny fae0a7c069 uasync: cast function pointers in socket_add log to void* 2026-09-20 01:18:33 +03:00
evgeny b33caa56b8 uasync: pass socket name to all add_socket call sites 2026-09-20 01:13:38 +03:00
evgeny c36cebe357 uasync: add socket name diagnostics and HUP/ERR auto-unregister safety net 2026-09-20 01:11:30 +03:00
evgeny 90520a83ff topo_group_connect: не подключаться к самому себе в авто-цикле
Phase 1/2/3 и on_up/on_down не фильтровали self: узел попадал в список
connected-пиров (get_connected_peers не исключает self) и разворачивал
node_conn_direct_open на собственные адреса (12 линков на 5C31->5C31).
Ручной путь (connect_node_once) фильтр уже имел.

Добавлен skip self в Phase1 init/cycle_restart, Phase2, Phase3 и в
on_up/on_down (self не помечается connected и не считается в active_conn_count).
2026-09-19 23:40:06 +03:00
evgeny 6b92964794 radio/android: PTT FGS microphone permission + детект потери микрофона
- FOREGROUND_SERVICE_MICROPHONE запрос + foregroundServiceType microphone|specialUse (Android 14+)
- RadioOverlayService.start: не стартовать без mic-разрешения, ServiceCompat.startForeground с TYPE_MICROPHONE
- RadioAudioEngine: micDead-флаг и лог при обрыве captureLoop/read
- radio.c: лог первого кадра burst на транзитных узлах
- SettingsScreen: категория radio в списке debug-категорий
2026-09-19 23:13:04 +03:00
evgeny 688785fc6e etcp: фикс зависшего reinit_pending после реинита готового соединения
etcp_conn_queue_set_ready() делает ранний выход по state!=0, поэтому при
реините уже готового соединения (peer restart / duplicate INIT / collision)
reinit_pending оставался в 1 навсегда. Добавленные в 841b3042 guard'ы
etcp_conn_input/etcp_output_try_assembly дропали все входящие пакеты.

Снятие reinit_pending + REINIT перенесено в etcp_conn_ready.
2026-09-19 23:13:04 +03:00
evgeny 5e955168d2 chatgui-android: PTT-оверлей — talking flow, цвет idle/talking, drag-lock
- RadioAudioEngine: StateFlow talking для реактивной подсветки кнопки
- RadioOverlayService: градиент idle/talking, drag-lock, сброс isShown при destroy
- ChatScreen: скрывать PTT-кнопку при активном оверлее, подсветка по talking
2026-09-19 21:17:38 +03:00
evgeny 841b3042cf etcp: фикс double-free буферов паковщика и повторных free после неудачного queue_data_put
- pn_send_to_etcp/pn_unpacker_cb: занулять pn->data/pn->recvpart ДО queue_data_put
  (ре-энтрантный close/reinit в синхронной цепочке освобождал буфер повторно)
- etcp_output_try_assembly: гард state==2/reinit_pending + убрать re-put освобождённого entry
- etcp_conn_input: гард ре-энтрантного reinit/close в цикле секций, локальный etcp вместо pkt->link
- убраны повторные free после queue_data_put (он сам освобождает entry+dgram) в 6 местах
- диагностика: obj=%p в DOUBLE FREE, логи free dgram в pn_deinit/ack_recv
2026-09-19 21:17:33 +03:00
evgeny 4a785772be chatgui-android: PTT по volume-кнопкам (вверх/вниз) + синхронизация оверлея
- volume up/down обе держат PTT (holdCount), настройка radio_volume_ptt
- syncRadioOverlay при включении/выключении рации
2026-09-19 18:16:46 +03:00
evgeny 8a9184675a radio: дедупликация дублей в mesh + фикс OOB в hop_list
- radio_recv: кэш (src,stream,seq) с TTL 2с гасит кадры, пришедшие по второму пути (diamond/mesh)
- фикс записи за границу new_hops[hop_count] при hop_count==RADIO_MAX_HOPS
- счётчик c_dup_dropped + radio_dup_dropped() для диагностики
- тест test_radio_mesh (4 узла, diamond): C получает ровно N кадров, dup>0
2026-09-19 18:16:42 +03:00
evgeny b96ed8bd00 radio: PTT-радио в каналах (src/radio + chatgui + chatgui-android)
Новый модуль src/radio (radio/radio_audio/radio_headless) — push-to-talk
радио поверх topo-групп, доставка аудио в канал, headless-режим и тесты.
Интеграция в chatgui (ptt_hotkey_manager, radio_audio_engine, радионастройки,
вызовы) и chatgui-android (RadioAudioEngine, RadioOverlayService, UI).
2026-09-19 17:09:00 +03:00
evgeny 398078a28f headless/call: закрывать клиента и логировать при ошибке send() (EPIPE/ECONNRESET) 2026-09-19 10:43:04 +03:00
evgeny 6c42390fc2 utun: игнорировать SIGPIPE, чтобы send() в закрытый TCP-сокет не убивал демон 2026-09-19 10:32:57 +03:00
evgeny 1de1409699 conn_mgr: handle-based API (conn_mgr_open/close), фазы DIRECT/REVERSE/INDIRECT, тесты phases+handles 2026-09-19 09:31:08 +03:00
evgeny 734a414186 etcp: единый реестр svc_id + убрать коллизию CHAT/CONN_MGR (0x11)
Все ETCP_ID_*/ETCP_RT_ID_* сведены в etcp_api.h (единственное место
определения) с реестром и предупреждением про коллизии в пределах одного
пространства имён. Убраны локальные define из topo_group.h,
topo_group_invite.h, db_sync.h, chat_sync.h, chat_join.h; хардкод 0x31 в
member_sync.c заменён на ETCP_RT_ID_MEMBER_SYNC.

Коллизия: chatgui-десктоп биндил мёртвый ETCP_RT_ID_CHAT 0x11 поверх
ETCP_RT_ID_CONN_MGR 0x11 — затирался conn_mgr_router_recv_handler, из-за
чего INDIRECT-обмен conn_mgr не работал и голос звонка не устанавливался.
Удалён мёртвый код recvCallback/messageReceived/send в utun_node.{cpp,h}.
2026-09-19 00:18:39 +03:00
evgeny 6d3ad965ee topo: remember REQUEST_TABLE for not-yet-created groups, fulfill on create
При REQUEST_TABLE для ещё не созданной группы (CHAT-канал не загружен) пир
дропал запрос, и проситель навсегда не узнавал таблицу — односторонняя
видимость (звонок android→linux падал «peer offline»). Теперь запрос
запоминается в pending_table_reqs[32] и выполняется при создании группы
(topo_group_fulfill_table_reqs → handle_request_table).

Попутно: test_chat_join_e2e — критерий успеха через CHAT_EVT_CONNECT_RESULT
(JOIN_READY) вместо senders_list; doxygen-комментарии в etcp_api.h.
2026-09-18 23:36:45 +03:00
evgeny 8bfb456161 etcp: fix OOB/DoS in packet parsing and ping path
- FILLER: drop (uint16_t) truncation in fill_len bound (OOB pointer)
- ACK: require len >= ETCP_ACK_BASE_SIZE (8); wrap-aware clamp of till
  to next_tx_id + 16MB cumulative-ACK iteration limit (DoS)
- ping: bound len before sc_encrypt (stack overflow), ulen bound,
  allocate ETCP_DGRAM + PACKET_DATA_SIZE (heap overflow)

Signed-off-by: uTun <dev@utun>
2026-09-18 17:58:40 +03:00
evgeny 1340ab123b reality/stcp: fix OOB read in key_share parse, padding clamp, shbuf leak
- reality_parse_client_hello: bound shares_len by extension data length
  (len-2) to prevent stack-buffer-overflow from malformed ClientHello
- stcp handshake: reject padding_size > STCP_HS_PADDING_MAX (512)
- reality_ch_body_cb: free shbuf on stcp_try_send error (leak)
- tests: fuzz key_share parse; raw-socket handshake control/clamp/garbage

Signed-off-by: uTun <dev@utun>
2026-09-18 17:20:19 +03:00
evgeny e7fc69bb1d topo: комментарии к функциям topo_node/topo_group
conn_mgr: src node_id вместо conn->peer_node_id, препенд ETCP_RT_ID_CONN_MGR к dgram, bind CONN_MGR после etcp_router_init

call: guard CALL_ST_CONNECTING при accept
2026-09-17 17:30:05 +03:00
evgeny 1fce405204 debug: вычистить логи из категории DEBUG_CATEGORY_DEBUG (удалить дампы, перекатегоризовать ERROR-проверки в ETCP) 2026-09-17 00:17:32 +03:00
evgeny e6a4ffd418 reality: fix leak of ClientHello init buffer in reality_server_start_relay 2026-09-17 00:05:42 +03:00
evgeny 1f1df4f437 mem: детект аномально больших аллокаций (LARGE ALLOC log + calloc overflow guard) 2026-09-16 21:12:46 +03:00
2425 changed files with 625390 additions and 53713 deletions

No files matched your search

+10
View File
@@ -2,7 +2,10 @@
/build/
build-win/
tools/chatgui/build/
tools/chatgui/rlottie_build/
tools/chatgui/ffmpeg/ffmpeg_build/
tools/chatgui/qt_multimedia/build/
tools/lightsout/build/
# Build outputs
*.o
@@ -11,6 +14,8 @@ tools/chatgui/ffmpeg/ffmpeg_build/
*.a
*.so
*.so.*
# Prebuilt native runtime для Android VAD (onnxruntime) — коммитим несмотря на *.so
!tools/chatgui-android/app/src/main/jniLibs/*/libonnxruntime.so
/utun
/src/utun
test_serialize
@@ -28,6 +33,7 @@ index.html
*.exe
# Autotools
/.utun-build-state*
Makefile
!tools/etcpmon/Makefile
Makefile.in
@@ -72,6 +78,8 @@ callgrind.out.*
tests/*.log
tests/*.trs
tests/logs/
/db_a/
/db_b/
# Mass update logs
logs/
@@ -80,6 +88,7 @@ logs/
tests/test_*
!tests/test_*.c
!tests/test_*.h
!tests/test_*.py
!tests/test_*.conf
!tests/test_*.json
tests/bench_*
@@ -108,6 +117,7 @@ tools/proxy/udp_proxy
# Reference projects (not part of utun)
tools/tdesktop-dev/
/hardware/
# Debug/temp artifacts
*.bak
+444 -134
View File
@@ -32,12 +32,17 @@ This file contains essential information for AI coding agents working in the uTu
Доствп на узел colo2: ssh -p44322 logs@colo2
Структура .h файлов:
- в начале краткое и понятное описание: что делает модуль, как пользоваться.
- поля структур также кратко описываем - что, для его, если есть нюансы/значения
- для функций: описываем назначение, как пользоваться, описание аргументов, возврата. кратко но понятно.
## Quick Reference
**Repository:** uTun - Secure VPN tunnel with ETCP protocol
**Repository:** uTun — общее сетевое ядро ETCP, независимо запускаемые UTUN и P2P-чат
**Language:** C (C99)
**Build System:** GNU Autotools (autoconf/automake)
**Cryptography:** OpenSSL (AES-CCM, X25519, SHA256)
**Cryptography:** OpenSSL (AES-CCM, X25519, Ed25519, SHA256)
## Build Commands
@@ -51,9 +56,19 @@ This file contains essential information for AI coding agents working in the uTu
powershell build_full.bat # запускает bash build.sh --full через MSYS2 UCRT64
```
### Build (FreeBSD)
```sh
# Первичная установка инструментов от root:
pkg install -y bash gmake autoconf automake libtool pkgconf openssl python3
./build.sh -j4 # общий скрипт; автоматически выбирает gmake и Clang
./build_bsd_full.sh -j4 # полная сборка через общий скрипт
```
Python 3 нужен для проверок скрипта сборки. SHA-256 берётся из базовой системы FreeBSD.
### Incremental Build
```bash
./build.sh -j4 # make с авто-конфигурацией если надо
./build.sh -j4 # инкрементальная сборка, конфигурация и очистка при необходимости
./build.sh --no-gui -j4 # только ядро и тесты, без отдельной сборки GUI
```
```powershell
powershell -Command ".\build.bat" 2>&1 # Windows, логи: build_win.log
@@ -68,9 +83,10 @@ make distclean # Clean everything including configure files
### Partial Builds
```bash
cd lib && make # Build only the library (libuasync.a)
cd src && make # Build only the main program
cd tests && make # Build only tests
make -C lib # базовые библиотеки
make -C lib/libopus # встроенный Opus
make -C src # основной бинарник src/utun (библиотеки уже должны быть собраны)
make -C tests # тесты (используют объекты src/)
```
### Direct Build (Windows, без autotools)
@@ -86,7 +102,7 @@ python3 tools/chatcli members <ch_id> # мемберы с полн
python3 tools/chatcli messages <ch_id> [count] # последние сообщения
python3 tools/chatcli send <ch_id> "text" # отправить сообщение
python3 tools/chatcli invite <ch_id> # создать invite-ссылку
python3 tools/chatcli connect <utun://...> # join по ссылке
python3 tools/chatcli connect 'utun://...' # join по ссылке
python3 tools/chatcli create "Name" # создать канал
python3 tools/chatcli listen # слушать события (Ctrl+C выход)
```
@@ -94,13 +110,14 @@ python3 tools/chatcli listen # слушать событи
### ASAN Build (AddressSanitizer, Linux)
```bash
./build.sh --asan -j4 # lib/ + src/ only (tests not ASAN-compatible)
./build.sh --asan -j4 # собирает lib/ + src/; тесты этот режим скрипта пропускает
```
Запуск с ASAN (detect_leaks отключены чтобы не спамить при shutdown):
```bash
ASAN_OPTIONS=detect_leaks=0:halt_on_error=0 ./src/utun -f -p /tmp/utun.pid -l /tmp/utun.log
ASAN_OPTIONS=detect_leaks=0:halt_on_error=0:log_path=/tmp/utun_asan ./src/utun -f -p /tmp/utun.pid -l /tmp/utun.log
```
Краш-логи ASAN пишутся в `/tmp/utun_asan.<pid>`.
В этом примере отчёты ASAN пишутся в `/tmp/utun_asan.<pid>` благодаря `log_path`.
Для отдельного теста нужно собирать его зависимости с теми же sanitizer-флагами; обычные и ASAN-объекты не смешивать.
## Test Commands
@@ -118,13 +135,14 @@ cd tests/
./test_etcp_two_instances
```
### Run Single Test with Debug Info
### Build and Run a Single Test
```bash
cd tests/
gcc -I../src -I../lib -I../tinycrypt/lib/include \
-o my_test test_file.c ../src/*.c ../lib/*.c ../tinycrypt/lib/source/*.c
./my_test
make -C tests test_services
cd tests && ./test_services
```
Использовать цель из `tests/Makefile.am`: ручная компиляция `src/*.c` пропускает подкаталоги и добавляет лишний `main`.
Уровни и категории диагностики настраиваются в самом тесте через `debug_set_level` / `debug_set_category_level`.
Проверки самого скрипта сборки запускаются отдельно: `make -C tests check-build-script` (нужен Python 3); в `./check.sh` они не входят.
## Code Style Guidelines
@@ -137,7 +155,7 @@ gcc -I../src -I../lib -I../tinycrypt/lib/include \
### Formatting
- **Indentation:** 4 spaces, no tabs
- **Braces:** Same line for functions, new line for control structures:
- **Braces:** Открывающая скобка на строке функции или условия:
```c
int function(void) {
if (condition) {
@@ -145,7 +163,7 @@ gcc -I../src -I../lib -I../tinycrypt/lib/include \
}
}
```
- **Comments:** Primary language is Russian for business logic, English for API docs
- **Comments:** Краткие описания на русском; сохранять принятые имена API и протокольных полей.
- **Line Length:** Aim for 80-100 characters, but can go up to 150 if logically coherent
### Include Order
@@ -201,7 +219,7 @@ sc_context_t ctx;
sc_init_ctx(&ctx, &my_keys);
// 2. Set peer public key (for key exchange)
sc_set_peer_public_key(&ctx, peer_public_key, SC_PEER_PUBKEY_HEX); // 0=bin, 1=hex
sc_set_peer_public_key(&ctx, peer_public_key_bin, SC_PEER_PUBKEY_BIN); // 32 бинарных байта; HEX — для hex-строки
// 3. Ready for encrypt/decrypt
sc_encrypt(&ctx, plaintext, plaintext_len, ciphertext, &ciphertext_len);
@@ -227,69 +245,107 @@ debug - отладка: всё что нужно для понимание су
info - сообщения для пользователя о работе. мы должны видеть в читаемом виде понятные и осмысленные сообщения о каких-либо значимых действиях с точки зрения логики работы модуля или приложения
warn / error - ошибки и предупреждения (аномалии). должны быть во всех ошибочных ветках. Молча вываливаться с ошибкой нельзя, все ошибки и предупреждения должны логироваться.
### Debug Categories (28 категорий)
```
NONE=0, UASYNC=1, LL_QUEUE=2, CONNECTION=3, ETCP=4, CRYPTO=5, MEMORY=6,
TIMING=7, CONFIG=8, TUN=9, ROUTING=10, TIMERS=11, NORMALIZER=12, BGP=13,
SOCKET=14, CONTROL=15, DUMP=16, TRAFFIC=17, DEBUG=18, GENERAL=19, NAT=20,
KEEPALIVE=21, ETCPROUTE=22, BBR=23, ETCP_DUMP=24, CONNECTIVITY=25, DB_SYNC=26,
MEMBER_SYNC=27
```
### Debug Categories
Актуальные имена и константы — в `lib/debug_config.h`, текстовые имена — в `lib/debug_config.c`.
Основные: `sys`, `connection`, `etcp`, `crypto`, `config`, `tun`, `routing`, `timers`, `bgp`,
`socket`, `control`, `dump`, `traffic`, `debug`, `general`, `nat`, `keepalive`, `etcp_route`,
`media`, `etcp_dump`, `chat`, `chat_sync`, `member_sync`, `proxy`, `video`, `reality`, `dm`, `call`, `radio`, `vad`, `aec`.
UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в ETCP; старые числовые списки не использовать.
### Настройка отладки
- В конфиге: `debug = etcp=trace,config=info` (формат: `категория=уровень,...`)
- В INI-конфиге: секция `[debug]`, каждая категория отдельной строкой (`etcp=trace`, `config=info`).
- Строку `etcp=trace,config=info` принимает `debug_parse_config()`; GUI хранит её в `[gui] debug_categories`.
- В коде: глобальный уровень и per-category уровни из `debug_config_t g_debug_config`
- Макросы: `DEBUG_ERROR(cat,fmt,...)` `DEBUG_WARN` `DEBUG_INFO` `DEBUG_DEBUG` `DEBUG_TRACE`
- `log_dump(prefix, data, len)` — hex dump в лог
- `log_dump(level, category, prefix, data, len)` — hex dump в лог
### Dual Output
- Консоль и файл настраиваются раздельно (`debug_set_console_level`, `debug_set_file_level`)
- Фильтр уровней общий для выходов; `debug_enable_console()` включает/выключает консоль.
- `debug_enable_file_output(path, truncate)` / `debug_disable_file_output()`
## Architecture
### Ядро, сервисы и владение ресурсами
- `utun_instance_create*()` создаёт ядро; `utun_core_start()` запускает общие сетевые службы.
- `utun_service_start/stop()` управляет UTUN-группой, TUN/NAT и запросами к пирам из конфига.
- `chat_service_start/stop()` управляет чатом и CHAT-группами. Чат не требует UTUN; desktop и Android запускают ядро и чат явно.
- Ядро владеет общей SQLite (`db_path/chats.db`, без пути — `:memory:`), идентичностью, транспортом и маршрутизатором.
Остановка сервиса сохраняет БД и ресурсы другого сервиса. `utun_instance_destroy()` освобождает ядро, но не переданный `UASYNC`.
- Группа владеет NCD handle с начала CONNECTING. Инициатор хранит отменяемый `TOPO_PEER_REQUEST`;
закрытие своего запроса не разрывает транспорт других владельцев. Готовая сессия сохраняется у группы.
- UP означает работоспособный транспорт. READY означает завершённое согласование и обмен таблицей конкретной группы.
Recovery ждёт нужных маршрутов через READY-пиров; наличие `ETCP_CONN*` само по себе не гарантирует UP.
- JOIN добавляет подписанного мембера, Merkle распространяет запись. Доступ к CHAT-группе каждый узел даёт по своей таблице участников;
invite-ключ не даёт временного членства. Протокол описан в `src/chat/chat_join.h`, групповое согласование — в `src/routing_layer/topo_group.h`.
- `TOPO_NODE` — общая подписанная запись узла. Более свежий timestamp заменяет запись целиком, с полями и подписью;
адреса не версионируются отдельно. BGP обновляет запись и передаёт изменения NCD (см. `doc/node_snapshot.md`).
- BGP хранит один путь к назначению от каждого соседа. WITHDRAW удаляет только путь отправителя;
NODEINFO с прежним timestamp также обновляет путь. Выбор: живой путь с минимумом хопов, затем меньший ID соседа.
REINIT сохраняет пути до проверки нового снимка; TABLE_COMPLETE удаляет неподтверждённые, зависший обмен перезапускается.
- ETCP-router дописывает ID при транзите и отбрасывает повторное посещение для DATA/ACK/control.
Список переходов находится вне подписанного тела; формат описан в `src/routing_layer/etcp_router.h`.
Все операции с ядром выполняются в его uasync-потоке; stop/destroy — вне callbacks останавливаемых сервисов.
Порядок освобождения ресурсов и нюансы media workers: `doc/service_lifecycle.md`.
### Directory Structure
```
├── lib/ # Core libraries (18 .c + 20 .h + libopus/liblmdb)
├── lib/ # uasync, очереди, SQLite, Opus, SpeexDSP, Silero VAD, SoundTouch, LMDB
├── src/ # Main source code
│ ├── transport_layer/ # ETCP stack, crypto, STCP, normalizer, BBR (~30 файлов)
│ ├── routing_layer/ # Routing, BGP, conn_mgr, etcp_router, NAT detection (~20 файлов)
│ ├── chat/ # P2P чат, db_sync, merkle_sync, member_sync (17 файлов)
│ ├── proxy/ # SOCKS5, TCP/UDP/ICMP прокси (10 файлов)
│ ├── lwip_tcp/ # Встроенный lwIP TCP стек (7 файлов)
│ ├── media_delivery/ # Доставка медиафайлов (6 файлов)
│ ├── media_async/ # Асинхронный движок медиа (2 файла)
│ └── *.c/h # Корневые модули: utun, config, TUN, firewall, NAT, NTP, control (~14 файлов)
├── tests/ # ~70 тестов, 64 в check_PROGRAMS
│ ├── transport_layer/ # ETCP, сессии, crypto, STCP/REALITY, SOCKS-клиент, NCD, BBR
│ ├── routing_layer/ # Routing, группы/BGP, recovery, conn_mgr, etcp_router
│ ├── chat/ # P2P чат, join, db_sync, merkle_sync, member_sync
│ ├── dm/ # Личные сообщения, E2E-вложения и offline-mailbox
│ ├── call/ # Звонки и общий голосовой стек
│ ├── radio/ # Групповая PTT-рация
│ ├── stream/ # Прямые трансляции: подписанные RS-блоки, выбор поставщиков, аудио/видео
│ ├── member_files/ # Файловое хранилище участников CHAT-группы и асинхронные передачи
│ ├── local_transport/ # Обнаружение устройств и доставка приглашений в локальной сети по UDP
│ ├── proxy/ # SOCKS5, TCP/UDP/ICMP прокси
│ ├── lwip_tcp/ # Встроенный lwIP TCP стек
│ ├── media_delivery/ # Блоки медиа каналов и передача неизменяемых файлов
│ ├── media_async/ # Фоновые задачи, метаданные вложений, подготовка голоса/видео
│ ├── video/ # Пробинг и транскодирование видео через FFmpeg
│ ├── dnsmasq/ # Архив исходников для встроенной сборки dnsmasq
│ └── *.c/h # utun, instance, config, TUN, firewall, NAT, NTP, control, broadcast
├── tests/ # Состав тестов и цели запуска: tests/Makefile.am
├── doc/ # Technical Specifications
├── tools/ # Auxiliary tools
│ ├── etcpmon/ # GUI монитор ETCP
│ ├── chatgui/ # GUI чат (Qt 6 с Qt 5 fallback, сборка CMake)
│ ├── chatgui-android/ # Android P2P чат (Jetpack Compose + libutun_lite)
│ ├── logreceiver/ # Приём UDP-логов Android
│ ├── chat_tcp_test/ # Сценарий проверки чата через TCP
│ ├── lightsout/ # Отдельная игра Lights Out на Qt
│ ├── lightsout-android/ # Android-версия Lights Out
│ ├── tdesktop-dev/ # Референс: Telegram Desktop (только для изучения)
│ ├── proxy/ # UDP прокси для тестов
│ └── bping/ # BPing (bandwidth ping)
│ ├── bping/ # BPing (bandwidth ping)
│ └── chatcli # Headless CLI; описание команд — chatcli_commands.txt
├── tinycrypt/ # TinyCrypt crypto library (external)
├── net_emulator/ # Network emulator (delays, loss, reordering)
└── c2/ # Test instance 2 (конфиг и бинарник для тестов)
└── net_emulator/ # Network emulator (delays, loss, reordering)
```
### File Overview
Пути ниже относительны к каталогу секции; `name.c/h` означает пару `.c` и `.h`.
Перечислены модули проекта; внутренние файлы сторонних библиотек сгруппированы по каталогам.
**Core (src/)**
- `utun.c` - Main program entry point, CLI parsing, daemon mode
- `utun_instance.c/h` - Root instance lifecycle, config loading, all submodule init
- `utun_instance.c/h` - Создание ядра и независимый жизненный цикл UTUN/чата, владение общими ресурсами
- `tun_if.c/h` - TUN interface API (init/write/close, cross-platform)
- `tun_linux.c` `tun_freebsd.c` `tun_windows.c` - Platform-specific TUN implementations
- `tun_route.c/h` - TUN routing table sync
- `config_parser.c/h` - INI-style config file parsing
- `config_updater.c/h` - Config file modification utilities
- `config_updater.c/h` - Проверка и сохранение согласованных X25519-ключей и node_id в INI-конфиге
- `control_server.c/h` - Control/monitoring server (etcpmon backend API)
- `firewall.c/h` - Firewall rules (per-interface filtering)
- `eim_nat.c/h` - Endpoint-Independent Mapping NAT engine
- `nat_transport.c/h` - NAT transport layer (packet relay)
- `ntp_time.c/h` - NTP time synchronization
- `ntp_node_time.c/h` - Inter-node time synchronization
- `nat_transport.c/h` - Передача IPv4 между отдельным TUN и удалённым NAT-провайдером через UTUN-router; локальный провайдер использует eim_nat
- `ntp_time.c/h` - Асинхронная NTP-синхронизация: поправка времени instance без изменения часов ОС
- `ntp_node_time.c/h` - Получение временной поправки от синхронизированных ETCP-пиров и диагностика расхождения часов
- `broadcast.c/h` - Широковещательная рассылка данных по topo-группе (UUID-дедупликация, TTL)
- `video/video.c/h` - Пробинг и транскодирование видео (FFmpeg, опционально; H.264/MP4 ≤720p)
- `dnsmasq/` - Архив dnsmasq-2.93.tar.xz для встроенной сборки
@@ -298,74 +354,141 @@ MEMBER_SYNC=27
- `etcp.c/h` - ETCP protocol implementation (inflight queues, retrans, ACK, RTT/jitter)
- `etcp_api.c/h` - ETCP public API (send/recv/bind callbacks)
- `etcp_connections.c/h` - Socket and link management, INIT handshake, keepalive, PING/PONG
- `etcp_session.c/h` - Согласование эпох ETCP-сессии через HELLO/CHALLENGE/CONFIRM и проверка принадлежности DATA сессии
- `etcp_loadbalancer.c/h` - Multi-link load balancing with traffic shaper
- `etcp_debug.c/h` - ETCP packet dump/formatting
- `etcp_debug.c/h` - Диагностический разбор секций ETCP_DGRAM и форматирование IPv4-адресов
- `etcp_dump.c/h` - ETCP дамп/декодирование пакетов
- `etcp_bbr.c/h` - BBR congestion control for ETCP
- `etcp_connect.c/h` - ETCP outbound connections
- `etcp_keepalive.c/h` - Keepalive-пакеты, адаптивный период, смена режима standby/normal (мобильные узлы)
- `auto_socket.c/h` - Автосоздание UDP+TCP сокетов на всех интерфейсах и линков к ETCP-соединениям (`auto_sockets=yes`)
- `pkt_normalizer.c/h` - Packet fragmentation/reassembly (packer/unpacker)
- `packet_dump.c/h` - Packet hex dump utility
- `dummynet.c/h` - Network emulator integrated into utun (for testing)
- `secure_channel.c/h` - AES-CCM encryption with X25519 key exchange, pubkey obfuscation
- `packet_dump.c/h` - Текстовая сводка IPv4-пакета: адреса, поля транспорта и короткий hex-фрагмент
- `dummynet.c/h` - Двунаправленный UDP-эмулятор между заданными endpoint: задержка, ограничение скорости и случайные потери
- `secure_channel.c/h` - X25519, пакетное AES-128-CCM, потоковое AES-CTR, подписи Ed25519 и обфускация публичного ключа
- `etcp_padding.c/h` - Выбор длины случайного padding и периодическое обновление диапазона для instance/соединения
- `etcp_tx_stats.c/h` - Общая статистика исходящих очередей, inflight и подтверждённых за секунду байтов ядра
- `crc32.c/h` - CRC32 checksums
- `stcp.c/h` - STCP протокол (Secure TCP)
- `stcp_server.c/h` - STCP сервер
- `stcp_client.c/h` - STCP клиент
- `stcp_link.c/h` - STCP линк-уровень
- `node_conn_direct.c/h` - Direct config-based connections
- `socket_monitor.c/h` - Socket state monitoring
- `stcp.c/h` - Зашифрованные кадры поверх TCP: согласование ключей/эпох, AES-CTR, CRC, очереди и закрытие соединения
- `stcp_server.c/h` - Приём входящих STCP-соединений, handshake и передача готового соединения владельцу
- `stcp_client.c/h` - Исходящее STCP-подключение, в том числе через SOCKS5 и REALITY
- `stcp_link.c/h` - Подключение STCP к ETCP_LINK: передача пакетов, backpressure и жизненный цикл TCP-линка
- `socks_client.c/h` - Исходящий SOCKS5-транспорт: TCP CONNECT и UDP ASSOCIATE с переподключением control-сокета
- `node_conn_direct.c/h` - Общий прямой транспорт к пиру с отдельным handle каждого владельца; обновление линков по адресам узла
- `socket_monitor.c/h` - Наблюдение за адресами интерфейсов и маршрутами ОС, обновление сетевого состояния ETCP-сокетов
- `reality.c/h` - REALITY-style TLS ClientHello/ServerHello камуфляж для STCP
- `reality_fingerprint.c/h` - Статические отпечатки (cipher suites, groups, ALPN) для REALITY-камуфляжа
- `reality_io.c/h` - Внешний REALITY-handshake и поток защищённых записей STCP, Finished, replay-защита и выбор relay
- `reality_record.c/h` - TLS-подобные AES-128-GCM записи: вывод ключей, счётчики направлений, padding и KeyUpdate
- `reality_relay.c/h` - Релей неавторизованных клиентов на реальный HTTPS-сайт
- `stun_nat.c/h` - Проверка mapping/filtering NAT через внешние STUN-серверы, RFC 5780 и кеш результатов по IP/интерфейсу
- `call_ring.c/h` - Кольцевой трейс контрольных точек освобождения ETCP/STCP-ресурсов для диагностики teardown/UAF
**BBR (src/transport_layer/BBR/)**
- `bbr_v3.c` - BBR congestion control algorithm v3
**Routing Layer (src/routing_layer/)**
- `routing.c/h` - Routing table (local)
- `route_lib.c/h` - Routing library
- `route6_lib.c/h` - IPv6 routing
- `route_ping.c/h` - Route ping probing (NAT check, liveness)
- `route_connectivity.c/h` - Route connectivity checks
- `topo_group.c/h` - BGP-like route exchange between nodes (NODEINFO/WITHDRAW, изолированные группы UTUN/CHAT)
- `topo_group_connect.c/h` - Авто-подключение к узлам CHAT-группы (3 фазы, бесконечный цикл)
- `topo_group_invite.c/h` - Invite/join канала через прямое ncd-подключение (INVITE_INFO_REQ/RESP)
- `topo_node.c/h` - Node management (модель узла: TOPO_NODE/TOPO_GROUP_NODE, сериализация, node_registry)
- `topo_node_sqlite.c/h` - SQLite persistence for nodes
- `topo_recovery.c/h` - Восстановление каскадно отвалившихся узлов после разрыва соединения
- `routing.c/h` - Обмен IPv4-пакетами UTUN между локальным TUN и сервисом DATA ETCP-router
- `route_lib.c/h` - Локальная таблица IPv4-подсетей UTUN: добавление/удаление маршрутов и поиск узла назначения
- `route6_lib.c/h` - Локальная таблица IPv6-подсетей на radix tree с поиском по самому длинному префиксу
- `route_ping.c/h` - Пинг цели через явно выбранного BGP-посредника для NAT-проверки
- `route_connectivity.c/h` - Прямые UDP/TCP-пробы адресов узла для оценки достижимости и RTT при выборе пиров
- `topo_group.c/h` - Сессии UTUN/CHAT (JOIN/ACCEPT, эпохи, READY), групповые запросы, NODEINFO/WITHDRAW и владение NCD
- `topo_group_connect.c/h` - Подбор пиров CHAT-группы по роли: суперузлы → desktop → mobile; история/RTT внутри класса, backoff и standby burst
- `topo_group_invite.c/h` - Получение описания канала через INVITE_INFO_REQ/RESP; добавление мембера реализовано в chat_join/chat_sync
- `topo_node.c/h` - Модель TOPO_NODE/TOPO_GROUP_NODE, подписанные снимки узлов, сериализация и общий node_registry
- `topo_node_sqlite.c/h` - Хранение подписанных снимков узлов, адресов, каналов и блоков мемберов в общей SQLite
- `topo_recovery.c/h` - Восстановление потерянных маршрутов группы через READY-сессии, отмена попыток при stop
- `conn_mgr.h` + `conn_mgr_core.c`/`conn_mgr_indirect.c`/`conn_mgr_monitor.c` + `conn_mgr_priv.h` — Connection Manager (handle-based API, 3-phase DIR/REV/IND)
- `etcp_router.c/h` - ETCP router/multiplexer (мультиплексирование каналов, transit forwarding)
- `nat_detection.c/h` - NAT type detection
- `etcp_router.c/h` - Надёжные логические каналы сервисов поверх BGP-маршрутов: ACK, окна, транзит и защита от циклов
- `route_tx_stats.c/h` - Скользящее окно подтверждённых payload-байтов логического канала для оценки скорости доставки
- `multicast.c/h` - Рассылка списку узлов группы с разделением маршрута на ветви, локальными подписками и отчётами о потерях
- `nat_detection.c/h` - Проверка mapping и доступности входящих рабочих сокетов через ETCP-пиров с учётом предварительных STUN-измерений
- `address_profile.h` - Профиль endpoint: изменение адреса, доступность входящих и источник измерения ETCP/STUN
- `sock_match.c/h` - Классификация локальных сокетов и адресов пира, отбор совместимых пар для прямого подключения
- `route_crypto.c/h` - Пред/пост-обработка SVC_ROUTE пакетов (encrypt-then-sign)
**Chat (src/chat/)** — децентрализованный P2P чат: сообщения и участники автоматически синхронизируются между всеми узлами канала без центрального сервера.
- `chat_core.c/h` - Главный модуль чата. Единственная точка входа из GUI: принять сообщение, создать канал, изменить настройку. Управляет БД и жизненным циклом всех chat-модулей
- `chat_core.c/h` - API сообщений, каналов, профиля и настроек; chat_service_start/stop управляют чат-сервисом поверх общей БД ядра
- `chat_core_priv.h` - Внутренний API для частей chat_core: общий контекст и утилиты БД. Снаружи не используется
- `chat_sync.c/h` - Связывает чат с ETCP-сетью: отслеживает появление/разрыв соединений, обновляет онлайн-статус узлов, запускает синхронизацию участников каналов, обрабатывает приглашения
- `chat_event.c/h` - Доставка событий из ядра чата в GUI. Единый механизм: любой модуль отправляет событие (новое сообщение, смена участников, статус), GUI получает через один обработчик
- `chat_setting.c/h` - Настройки чата: проверяет корректность значений, хранит текущие. Используется и headless-парсером конфига, и GUI. Не зависит от других модулей
- `db_sync.c/h` - Автоматическая репликация данных между подключёнными узлами. Запись на одном узле — появляется у всех остальных. Криптоподписи и цепочка хешей защищают от подделок
- `chat_setting.c/h` - Проверка и хранение настроек чата per-instance; общая логика для конфигурации и GUI
- `chat_join.c/h` - Регистрация invite-ключа с ACK, пересылка запроса инвайтеру и добавление подписанного мембера; контракт join в заголовке
- `db_sync.c/h` - Репликация подписанных записей SQLite через прямые ETCP-соединения; расхождения по цепочке хешей, новые записи через PUSH
- `member_sync.c/h` - Синхронизация участников каналов поверх merkle_sync. Два подписанных блока (мембер/владелец), по-блочное сравнение версий, верификация подписей. Удаление — только битая запись
- `merkle_sync.c/h` - Универсальный движок синхронизации на Merkle-деревьях (5 уровней × 32 бакета, SHA256). Пиры обмениваются хешами и передают только различия; per-session out-очередь с backpressure. Не привязан к конкретному типу данных (коллбэки `data_ops`)
- `chat_profile.c` - Собственный профиль: имя узла, сетевые адреса, сохранение UI-состояния (часть chat_core)
- `chat_channel.c` - Создание и настройка каналов: готовит таблицы в БД, генерирует криптоключи, запускает подключение ко всем участникам (часть chat_core)
- `merkle_tree.c/h` - Производный индекс Merkle-хешей в SQLite; восстанавливается из данных модели, обновляется с ними в одной транзакции
- `chat_profile.c` - Подписанный профиль мембера: имя, аватар и опции сервисов; локальное UI-состояние (часть chat_core)
- `chat_channel.c` - Создание и настройка каналов: таблицы, криптоключи, CHAT-группа и планировщик подключения (часть chat_core)
- `chat_msg.c` - Отправка и приём сообщений: запись в локальную БД, автоматическая рассылка всем участникам канала (часть chat_core)
- `chat_feedback.c/h` - Подписанные реакции и ответы: версии состояния, сохранение отмен и Merkle-синхронизация между участниками
- `chat_poll.c/h` - Создание опросов, голосование, реакции и JSON-снимки результатов для UI/headless
- `chat_poll_codec.c` - Проверка и wire-кодеки опросов, ответов и реакций; общий каталог эмодзи (API в chat_poll.h)
- `chat_attachment.c/h` - Зашифрованные вложения канала: ключи, запросы доступа, ручное одобрение автора и сохраняемый outbox
- `chat_local.c/h` - Обнаружение устройств чата и обмен готовыми invite-ссылками через локальный UDP-транспорт
- `group_avatar.c/h` - Подписанная аватарка канала: хранение версии в SQLite, проверка подписи и передача блоков через router
- `chat_status.c` - Сбор диагностики: текущее время, активные соединения, типы NAT. Отправляется в GUI (часть chat_core)
- `chat_member.c/h` - Единая структура мембера для отображения в GUI (десктоп/headless/Android), фиксированная сериализация на проводе
- `chat_admin.c/h` - Передача канального приватного ключа (прав админа) другому узлу
- `chat_whisper.c/h` - Whisper speech-to-text транскрипция голосовых сообщений (опционально, асинхронно через media_async)
- `chat_headless_control.c/h` - TCP control-socket для headless chat CLI (JSON line protocol)
- `invite_build.c/h` - Сборка invite-ссылок utun:// (выбор лучшего узла + адреса)
- `invite_link.c/h` - Формат invite-ссылок utun:// для каналов (base64: version|password|channel_id|pubkey|addrs)
- `invite_link.c/h` - Кодирование utun://: версия, пароль, channel_id, join_key, Reality-параметры, ключ и адреса узла
**Личные сообщения (src/dm/)**
- `dm_core.c/h` - Беседы двух узлов, подписанные E2E-сообщения, SQLite/outbox, доставка через router/mailbox и квитанции
- `dm_crypto.c/h` - Вывод ID беседы и ключа X25519, AES-256-CCM сообщений и E2E-контейнеры медиа через media_crypto
- `dm_history.c/h` - Локальное удаление истории и скрытие бесед; поколения задач и отпечатки удалённых сообщений против повторов
- `dm_mailbox.c/h` - Offline-очередь суперузла: хранение подписанных сообщений и повтор доставки до квитанции получателя
- `dm_media.c/h` - Подготовка, доставка и публикация E2E-вложений; ciphertext-хранилище и отдельные квитанции файлов
- `dm_media_priv.h` - Внутренние SQL/control-операции для dm_media и dm_mailbox_media
- `dm_mailbox_media.c/h` - Сохраняемые задания суперузла для размещения медиа, доставки метаданных и удаления копий до DELETE_ACK
**Звонки (src/call/)**
- `call.c/h` - P2P аудио/видеозвонок: подписанный E2E-сигналинг, состояния, политика занятости и оптимизация пути через conn_mgr
- `call_priv.h` - Общее внутреннее состояние сессии для call.c и call_video_transport.c; доступ только из uasync
- `call_proto.h` - Wire-формат сигналинга, аудиокадров и управления видеотреком; треки/кодеки и причины завершения
- `call_audio.c/h` - Общий аудио-движок: кодирование/декодирование Opus, jitter-буфер и тоны, API feed/pull PCM
- `call_jitter.cpp/h` - FIFO Opus, адаптивный сетевой запас, декодирование на pull и восстановление воспроизведения после пауз
- `call_jitter_window.h` - Окно из десяти секундных интервалов для оценки глубины очереди и изменения задержки доставки
- `call_clock.h` - Метки времени захвата и снимок реально проигранного аудио для синхронизации видеотрека
- `call_delay.cpp/h` - Уменьшение накопленной задержки PCM прямым ускорением и SoundTouch с сохранением исходной шкалы времени
- `call_timeline.cpp/h` - Карта исходного PTS через обработку SoundTouch до позиции аудиоустройства
- `call_video.c/h` - Общий формат H.264/H.265 видеотрека, согласование возможностей и сборка кадров из фрагментов
- `call_video_bitstream.c/h` - Проверка конфигурации и IDR без reorder, профиля/уровня и геометрии H.264/H.265; KEY-пробы кодеков
- `call_video_transport.c/h` - Отдельные router-каналы control/audio/video, backpressure, привязка видео к аудио и запросы KEY
- `call_video_rate.c/h` - Регулятор битрейта и допуска новых видеокадров по скорости доставки, RTT и долгу очереди
- `call_video_port.c/h` - Потокобезопасный обмен кадрами и командами между платформенными video workers и uasync-транспортом
- `call_video_playout.c/h` - Расписание показа по аудиочасам, ожидание/отбрасывание кадров и подтверждение фактического показа
- `call_video_fixtures.h` - Встроенные H.264/H.265 KEY-пробы для проверки базовых режимов кодека
- `call_video_fast_fixtures.h` - KEY-пробы видеорежимов с частотой 60 fps
- `call_video_fullhd_fixtures.h` - KEY-пробы видеорежимов Full HD
- `call_video_portrait_fixtures.h` - KEY-пробы видеорежимов в портретной ориентации
- `call_tones.c/h` - Генерация PCM-тонов паузы и завершения звонка
- `call_headless.c/h` - Отдельный TCP-аудиосокет headless-клиента: обмен PCM; сигналинг остаётся на control-сокете
**Рация (src/radio/)**
- `radio.c/h` - Передача Opus по CHAT-группе, подписки, дедупликация и пересылка по ветвям с подписчиками
- `radio_proto.h` - Wire-формат PTT: источник, поток, seq, FIN и hop-list против циклов
- `radio_audio.c/h` - Общий аудио-движок: независимые RX/TX, Opus, микширование источников, ручной PTT и VAD-автомат
- `radio_jitter.cpp/h` - Буфер кодированных кадров каждого источника с pre-roll и SoundTouch time-stretch на pull
- `radio_vad.h` - Ресемплинг 48→16 кГц и автомат авто-PTT с подтверждением речи, задержкой завершения и учётом занятого канала
- `radio_auto.h` - Общий автомат автопередачи по VAD/уровню звука, без захвата аудио и сетевого I/O
- `radio_call.c/h` - Адресное приглашение участника в рацию канала: сигналинг вызова, занятость, принятие и отмена
- `radio_headless.c/h` - TCP-аудиосокет headless-рации: PCM и команды начала/конца PTT
**Прокси (src/proxy/)**
- `socks_proxy.c/h` - SOCKS5 прокси
- `udp_proxy.c/h` - UDP прокси
- `icmp_proxy.c/h` - ICMP прокси
- `tcp_proxy_server.c/h` - TCP прокси (серверная сторона)
- `tcp_proxy_client.c/h` - TCP прокси (клиентская сторона)
- `proxy_protocol.h` - Общий TCP-протокол и управление потоком: CONNECTED, DATA, кредит WINDOW, упорядоченный FIN
- `socks_proxy.c/h` - Клиентские SOCKS5 CONNECT и HTTP proxy/CONNECT, DNS и передача потока выбранному exit-узлу
- `http_proxy.c/h` - Потоковый HTTP/1.x кодек: проверка заголовков, разбор тела/chunked и учёт потреблённых байтов для WINDOW
- `udp_proxy.c/h` - Передача UDP из TUN через exit-узел, сопоставление ответов и удаление неактивных потоков
- `icmp_proxy.c/h` - Проксирование IPv4 ICMP echo через raw socket exit-узла с восстановлением исходных id/seq
- `tcp_proxy_server.c/h` - Exit-сторона TCP-прокси: реальные исходящие сокеты, потоки по (peer, stream_id), окна и half-close
- `tcp_proxy_client.c/h` - Клиентская сторона TCP-прокси: адаптер TUN/lwIP и обмен с настроенным exit через ETCP-router
**lwIP TCP (src/lwip_tcp/)**
- `lwip_tcp.c/h` - lwIP TCP стек
@@ -374,31 +497,80 @@ MEMBER_SYNC=27
- `lwip_tcp_priv.h`, `lwip_tcp_opts.h` - Внутренние настройки lwIP
**Media Delivery (src/media_delivery/)**
- `media_delivery.c/h` + `media_delivery_proto.h` - Доставка медиафайлов, протокол
- `media_download.c/h` - Скачивание медиа
- `media_index.c/h` - Индексация медиафайлов
- `media_delivery.c/h` - Доставка блоков медиа каналов, учёт держателей, репликация доступности между суперузлами и relay
- `media_delivery_proto.h` - Кодограммы канального медиа: QUERY, BLOCK_REQ/CHUNK/DONE, HAVE_BLOCK и SUPER_REPL
- `media_download.c/h` - Загрузка блоков с выбором держателей, failover, контролем простоя, проверкой подписей и сборкой файла
- `media_index.c/h` - Индекс media_files: UUID, хеши и подписи блоков, асинхронная регистрация и удаление медиа канала
- `file_transfer.c/h` - Передача неизменяемого файла между заданными узлами; авторизация lookup и владение CM handle до завершения
**Media Async (src/media_async/)**
- `media_async.c/h` - Асинхронный движок (thread-per-task для crypto/file операций)
- `media_async.c/h` - Фоновые crypto/file-задачи: work в pthread, done в uasync; destroy ждёт workers и завершает ожидающие callbacks с CANCELLED
- `attachment.c/h` - Общие метаданные file/voice/video, проверка и компактная wire-сериализация
- `voice_file.c/h` - Worker-кодирование PCM в контейнер Opus с длительностью и waveform для desktop/Android
- `attachment_send.c/h` - Асинхронная подготовка голоса/видео и отправка в зафиксированный канал или DM
- `media_crypto.c/h` - Общие AES-256-CCM примитивы и порционное шифрование/проверка файлов для DM и групповых вложений
- `encrypted_file.c/h` - Контейнер группового вложения: шифрование метаданных/файла, проверка SHA256 и durable-публикация результата
**Трансляции (src/stream/)** — live-аудио/видео CHAT-группы с подписью источника, Reed–Solomon и раздачей через участников.
- `stream.c/h` - Жизненный цикл трансляции, локальные handles издателя/читателей, события и публикация подписок
- `stream_priv.h` - Внутренний доступ к сессиям, приём проверенных DATA/END и взаимодействие с планировщиком relay
- `stream_proto.h` - Форматы подписанной пачки и RS-частей, дескриптор источника, размеры и коды результата
- `stream_block.c/h` - Подпись пачки Ed25519 до RS-кодирования, разбор частей и проверка восстановленных данных
- `stream_buffer.c/h` - Ограниченное кольцо RS-частей: дедупликация, восстановление пачек, проверка подписи и вытеснение старых данных
- `stream_source.c/h` - Упаковка исходных байтов в подписанные RS-пачки, сброс неполной пачки по таймеру и завершение источника
- `stream_member.c/h` - Объявления источников и подписок в опциях подписанного мембера; разбор и проверка принадлежности источника
- `stream_wire.c/h` - Протокол выдач и relay: кодограммы управления, пути, метрики и подписанное завершение END
- `stream_network.c/h` - Выдача блоков через прямой ETCP, NCD-владение, управляющие очереди, аренда подписок и reverse-запросы
- `stream_optimizer.c/h` - Автоматический выбор и перенос поставщиков субпотоков, пробы доступности и привлечение relay
- `stream_metrics.c/h` - Оценка относительного отставания субпотока и истории проблем по часам источника без NTP
- `stream_load.c/h` - Учёт логической очереди DATA и её роста для обнаружения перегрузки раздающего узла
- `stream_media.c/h` - Формат uAV2: упаковка/проверка видеокадров, конфигурации кодека, PTS и Opus внутри FEC-пачек
- `stream_media_buffer.c/h` - Медиаиндекс общего RS-кольца и независимые курсоры audio/video; сборка кадров и восстановление с KEY
- `stream_publisher.c/h` - Общий потокобезопасный publisher desktop/Android: очередь готовых кадров, публикация и завершение с FIN
- `stream_viewer.c/h` - Независимые viewers: запрос ограниченных батчей по бюджетам треков, уведомления готовности и конца audio/video
- `stream_playback_audio.cpp/h` - Opus/SoundTouch и очередь готового PCM; ускорение без изменения высоты и привязка к позиции устройства
- `stream_playback_clock.c/h` - Общие часы воспроизведения и плавный догон live-потока по непрерывному запасу готового материала
**Файлы участников (src/member_files/)**
- `member_files.c/h` - Сервер и асинхронный клиент хранилища CHAT-группы: права доступа, запросы и события через защищённый router
- `protocol.c/h` - Wire-кодек файловых команд, снимки версий каталогов/файлов и токены временных загрузок
- `storage.c/h` - Серверные каталоги участников, квоты, файловые операции, временные загрузки и их очистка
- `transfer.c` - Передача файлов с CM handle, backpressure, дисковым worker, проверкой хеша и публикацией результата
- `disk.c/h` - Дисковые примитивы POSIX/Windows: безопасное разрешение путей без ссылок и I/O по 64-битному смещению
- `worker.c/h` - Единственный дисковый pthread с ограниченной очередью и возвратом результатов в uasync
- `private.h` - Внутреннее состояние запросов, передач, серверного хранилища и дискового worker
**Локальная сеть (src/local_transport/)**
- `local_transport.c/h` - Открытый UDP-транспорт LAN: обнаружение устройств, доставка сообщений с ACK/повторами и ограничения входящего потока
- `platform.c/h` - Снимок IPv4/IPv6 интерфейсов, broadcast/multicast-адреса, приём метаданных UDP и проверка локальности источника
- `protocol.h` - Wire-формат объявлений, сообщений и ACK: ID/эпохи устройств, ID запроса и проверка UTF-8 имени
**Libraries (lib/)**
- `u_async.c/h` - Async event loop (epoll/poll/select, timers via timeout_heap)
- `ll_queue.c/h` - Lock-free linked list queue with callbacks, hash index, threshold waiter
- `memory_pool.c/h` - Fast object pool allocator (pre-allocated blocks)
- `ll_queue.c/h` - Двусвязная очередь одного uasync-потока с callbacks, хеш-индексом и ожиданием свободного места
- `memory_pool.c/h` - Пул объектов: ленивое выделение и повторное использование, до 64 свободных объектов в кеше
- `debug_config.c/h` - Debug logging system (levels, categories, dual output, runtime config)
- `timeout_heap.c/h` - Min-heap for timer management (used by u_async)
- `mem.c/h` - Memory wrappers with leak tracking (`u_malloc`/`u_free`/`u_calloc`/`u_strdup`)
- `serialize.c/h` - Binary serialization utilities
- `reed_solomon.c/h` - Кодирование и восстановление пачки данных Рида—Соломона с настраиваемым числом субблоков и избыточностью
- `video_plane.c/h` - Копирование YUV-плоскости с поворотом 0/90/180/270°, учётом stride и проверкой границ без выделения памяти
- `swm_min.c/h` - Sliding window minimum (for RTT min tracking)
- `getmyip.c/h` - Get local IP / default route detection
- `getmyip.c/h` - Локальный IP, который ОС выберет для UDP к заданному адресу (bind/connect/getsockname)
- `myip.c` - My IP helper (no header)
- `socket_compat.c/h` - Cross-platform socket compatibility (Linux/FreeBSD/Windows)
- `platform_compat.c/h` - Cross-platform compatibility layer (byte order, time, random)
- `radix.c/h` - Radix tree for IP routing lookups
- `tcp_io.c/h` - TCP I/O abstraction (Windows IOCP, Linux epoll)
- `tcp_io.c/h` - Неблокирующий TCP поверх uasync/ll_queue: backpressure, FIN/close и callbacks
- `sqlite3.c/h` - SQLite3 amalgamation (embedded database)
- `opus_codec.c/h` - Opus audio codec wrapper
- `audio_compressor.c/h` - Audio dynamic range compressor
- `speex_aec.c/h` - Эхоподавление SpeexDSP: согласование playback/capture PCM через линию задержки и диагностика её заполнения
- `silero_vad.c/h` - Стриминговый VAD через ONNX Runtime: окна 512 отсчётов, 16 кГц моно, вероятность речи и сброс состояния
- `silero_vad_model.inc` - Встроенная ONNX-модель Silero VAD для silero_vad_create_default
- `json_flat.c/h` - Flat JSON parser
- `strbuf.c/h` - Безопасный растущий printf-буфер (замена snprintf-цепочек)
- `async_dns.c/h` - Асинхронный (неблокирующий) DNS-резолвер A-записей поверх uasync, адаптер над libdns
@@ -407,8 +579,20 @@ MEMBER_SYNC=27
- `dr_mp3.h` - MP3-декодер (single-header, на базе minimp3)
- `liblmdb/` - Встраиваемый key-value store LMDB
- `libopus/` - Встраиваемый кодек Opus
- `speexdsp/` - Встроенные исходники эхоканселлера SpeexDSP и KISS FFT
- `soundtouch-master/` - SoundTouch: изменение темпа аудио в jitter-буферах звонка и рации
- `wintun.h` - Wintun API header for Windows TUN driver
**Проверки (tests/)**
- `Makefile.am` - Состав тестовых целей, зависимости и отдельные проверки runner, service IDs и скрипта сборки
- `run_tests.py` - Запуск тестов ограниченным пулом с отдельными логами и последовательными барьерами для CPU/LAN-проверок
- `test_run_tests.py` - Проверки пула runner, эксклюзивного запуска, обработки ошибок и сигналов
- `test_service_ids.py` - Проверка уникальности ID транспортных и router-сервисов
- `test_build_script.py` - Регрессии выбора платформы, конфигурации и инкрементальной работы build.sh
- `stream_netns/` - Linux network namespaces: топологии, NAT/STUN-сценарии и проверка трансляций в изолированной сети
- `local_transport_ipv6.sh` - Проверка IPv6 link-local обнаружения и доставки в изолированной локальной сети
**Memory Pools in UTUN_INSTANCE:**
- `data_pool` — для данных пакетов (payload), используется input_queue/output_queue фрагментами
- `pkt_pool` — для struct ETCP_DGRAM (сетевые пакеты на отправку/приём)
@@ -416,7 +600,7 @@ MEMBER_SYNC=27
### Key Components
- **UASYNC:** One per thread. Async event loop (epoll/poll), timers via timeout_heap
- **LL_QUEUE:** Lock-free queue with auto-callback, hash index lookup, threshold waiter
- **LL_QUEUE:** Очередь с auto-callback, хеш-индексом и threshold waiter; не средство обмена между потоками
- **Memory Pool:** Fast allocation for hot-path objects (packets, inflight entries, fragments)
- **ETCP:** TCP-like reliable protocol with encryption, multi-link, load balancing
- **Secure Channel:** AES-CCM + X25519 key exchange, nonce-based encryption, pubkey obfuscation
@@ -432,6 +616,8 @@ MEMBER_SYNC=27
- Очереди забивать нельзя. Добавляй следующий элемент только когда очередь стала пустой.
- Порог задаётся через `queue_set_threshold(q, max_packets, max_bytes)`.
- Используй `queue_waiter_wait` для ожидания освобождения очереди до заданного порога.
- Handle ожидания обнуляется целиком, живёт до callback/отмены и отменяется до освобождения владельца.
Callback может быть синхронным. `queue_entry_free` не освобождает dgram — его освобождают отдельно.
### Чтение из очереди
- Используй `queue_set_callback`: при вызове callback обработай один или несколько элементов, потом вызови `queue_resume_callback`.
@@ -451,7 +637,8 @@ MEMBER_SYNC=27
## Config Rules
- В серверном конфиге только собственные ключи и нет секций `[client]`
- В клиентском конфиге есть собственные ключи и pubkey каждого сервера в секции `[client]`
- Chat-настройки хранятся в секции `[chatserver]` (принимается также `[chat]`). Парсер вызывает `chat_setting_set(key, value)` для каждого ключа — неизвестные ключи вызывают ошибку. Пример:
- Chat-настройки хранятся в `[chatserver]` (также `[chat]`). Парсер обрабатывает общие поля секции,
затем вызывает `chat_setting_set_state(&cfg->global.chat_settings, key, value)`; неизвестные ключи логируются как ошибка. Пример:
```ini
[chatserver]
storage_autoload=1
@@ -474,7 +661,8 @@ MEMBER_SYNC=27
Если видишь спам-логи - подумай как их выборочно отключить чтобы не мешали.
Для отладки добавляй в DEBUG_CATEGORY_DEBUG диагностические сообщения где надо. И включи эту категорию в настройках. Убирай только после проверки (путём запуска) когда все ошибки устранены.
сообщение выводится по или - либо debug_set_level(DEBUG_LEVEL_TRACE) - выводится ВСЁ независимо от настроек по категориям. Тоесть берется max(global level, category lavel)
Явный уровень категории заменяет глобальный. DEBUG_LEVEL_NONE наследует глобальный уровень;
DEBUG_LEVEL_DISABLED полностью отключает категорию, в том числе при глобальном TRACE (см. debug_should_output).
Твой бич - ты постоянно гадаешь и анализируешь код. Что приводит к снежному кобу ошибок и неверных гипотез. 10 раз повторяю - только логи логи логи и никакого гадания. Лоооги!!! правильные логи покажут всё с предельной точностью. Вся суть отладки - информативные логи
И смотри логи. не задавливай их grep-ом. лучше больше. единственное с чем борись - это бесполезные спам логи.
@@ -484,7 +672,8 @@ MEMBER_SYNC=27
Но полезные смотри всегда, и всегда оставляй логи которые выводятся нечасто.
Частые логи - это трафик которые >100 раз повторяются. Но которые мало раз обязательно оставлять и выводить.
можешь в тесте включить логи в нужный интервал чтобы не спамить. debug_set_level(DEBUG_LEVEL_TRACE) и выключить debug_set_level(DEBUG_LEVEL_NONE)
В тесте можно временно поднять нужные категории до TRACE, сохранив прежние уровни и восстановив их после участка.
Одного debug_set_level(DEBUG_LEVEL_NONE) недостаточно для отключения категорий с явно заданным уровнем.
Если видишь проблему и ее решение неочевидно то выстраивай диагностику вокруг неё пока не будет очевидно где и что происходит не так. Это базовое и обязательное требование к отладке.
Подробные логи ты должен выводить не обрезая всегда и анализировать. Если лог большой - выведи в файл и анализируй файл.
Рассуждение должно быть примерно таким:
@@ -526,7 +715,7 @@ MEMBER_SYNC=27
- Нельзя ничего восстанавливать из репозитория не спрашивая
- Для отладки не printf а DEBUG_*
- Запрещено прямое включение arpa/inet.h, sys/time.h, unistd.h — использовать ../lib/platform_compat.h + socket_compat.h
- Перед сборкой всегда make clean
- Меняй режим и флаги сборки через `./build.sh`: он отслеживает конфигурацию и очищает объекты только при необходимости.
- Все лишнее что менял при отладке - строго вернуть назад в состояние до вмешательства
## Написание кода
@@ -535,12 +724,17 @@ MEMBER_SYNC=27
- Обязательно наличие подробной диагностики в функциях кода которые не сильно спамят (не часто вызываются).
- Для каждого отладочного вывода подумай какая из доступной информация будет полезна чтобы можно было наиболее завершенно оценить состояние алгоритма и состояний влияющих на алгоритм.
## Оформление кода
- в .c: перед каждой функцией - краткое но понятное описание что делает функция (кроме совсем простых)
- в .h: в начале - описание модуля - для чего предназначен, как пользоваться, нюансы. Далее структуры с комментариями, далее публичные функции с описаниями (что делает, как пользоваться, какие аргументы, возврат, нюансы работы)
## chatgui (GUI Chat Client)
Chatgui — десктопный GUI-чат на Qt 6 (Qt 5 fallback), отдельный проект внутри репозитория. Не связан с autotools-сборкой utun.
Chatgui (бинарник `vibechat`) — десктопный чат на Qt 6 (Qt 5 fallback), отдельная CMake-сборка общего ядра.
Корневой `build.sh` дополнительно вызывает её, если уже существует `tools/chatgui/build/CMakeCache.txt`.
В chat gui интегрированы библиотеки utun. Чат и библиотеки работают в разных потоках. Поэтому нужно использовать семафоры, сокеты или другие механизмы синхронизации (uasync_post, uasync_memsync, uasync_get_wakeup_fd)
GUI работает в Qt-потоке, ядро и чат — в uasync-потоке. Команды передаются через
`gui_bridge_post_uasync()` / `uasync_post()`, события возвращаются через Qt-сигналы.
База данных sqlite в chatgui: можно писать (update) из потока utun / instance. можно только читать из gui потока.
@@ -548,38 +742,45 @@ Chatgui — десктопный GUI-чат на Qt 6 (Qt 5 fallback), отде
- **Язык:** C++20
- **Фреймворк:** Qt 6 (предпочитаемый) или Qt 5.15+ (Widgets + Network)
- **Сборка:** CMake 3.16+
- **БД:** SQLite3 (WAL mode, встроенный `db/sqlite3.c` amalgamation)
- **БД:** SQLite3 (WAL mode, компилируется общий `lib/sqlite3.c`)
- **Анимации:** rlottie (C API) + zlib (gzip-декомпрессия TGS)
### Сборка
```bash
# Установка зависимостей
sudo apt install librlottie-dev zlib1g-dev qt6-base-dev
sudo apt install librlottie-dev zlib1g-dev qt6-base-dev libssl-dev libx11-dev libxfixes-dev libpipewire-0.3-dev
# или qtbase5-dev для Qt 5 fallback
# Сборка
cd tools/chatgui && mkdir -p build && cd build
cmake .. && make -j4
./chatgui
./vibechat
```
### Конфиг и логи чатгуи
- **Конфиг:** `tools/chatgui/build/chatgui.cfg` (в `.gitignore`, содержит приватные ключи)
- **Конфиг:** `vibechat.cfg` рядом с бинарником (обычно `tools/chatgui/build/vibechat.cfg`, содержит приватные ключи)
- Секция `[gui]`: `debug_file`, `debug_level`, `debug_categories=cat=level,...`
- Секция `[control]`: `ip`, `port` для подключения etcpmon
- Секция `[ntp]`: синхронизация времени
- **Лог:** `tools/chatgui/build/chatgui.log` (путь задаётся в конфиге `debug_file`)
- **БД чата:** `tools/chatgui/build/chat_data/` (SQLite, путь из `db_path` в конфиге)
- **БД чата:** `chats.db` в каталоге `[gui] db_path` (по умолчанию `chat_data/` рядом с бинарником)
### Структура файлов (src/)
| Файл | Назначение |
|------|-----------|
| `main.cpp` | Точка входа, инициализация QApplication |
| `mainwindow.h/cpp` | Главное окно, QSplitter (ChannelList \| MessageList \| AccountList), трей |
| `chatview.h/cpp` | QListView с фоновым изображением, hover-сигнал, drag-to-select |
| `messagelist.h/cpp` | QStandardItemModel, stub-данные, инициализация анимаций, hover→activate |
| `main.cpp` | Точка входа, QApplication, язык интерфейса и запуск единственного экземпляра профиля |
| `single_instance.h/cpp` | Блокировка каталога профиля и передача запроса показа окна уже работающему экземпляру |
| `gui_language.h` | Выбор языка интерфейса независимо от регионального формата дат и чисел |
| `mainwindow.h/cpp` | Главное окно, каналы/DM, трей, события ядра, звонки, локальные приглашения и окна трансляций |
| `chatview.h/cpp` | Список сообщений: фон, hover, выделение текста и прокрутка истории мышью/клавиатурой |
| `messagelist.h/cpp` | Модель сообщений из БД, обновления доставки/медиа, анимации, состояние просмотра канала |
| `messagedelegate.h/cpp` | QStyledItemDelegate: бабблы, текст, цитаты, реакции, оверлей анимаций |
| `messagefeedback.cpp` | Действия MessageList: создание опроса, голосование, выбор реакции и показ результатов |
| `attachment_key_ui.cpp` | Список запросов на расшифровку групповых вложений и решения автора о выдаче ключа |
| `message_links.h/cpp` | Разбор границ utun:// и HTTP/HTTPS ссылок для подсветки и обработки нажатий в сообщении |
| `message_notification.h/cpp` | Уведомление о сообщении без захвата фокуса, переход в беседу и скрытие после активности пользователя |
| `user_activity_monitor.h/cpp` | Ожидание первой активности через системный idle time либо события приложения |
| `emoji.h/cpp` | EmojiData/EmojiCategory/EmojiType, 4 категории, `g_animatedEmojiMap` |
| `emojipanel.h/cpp` | Эмодзи-пикер: QTabWidget + QGridLayout, EmojiButton с hover-анимацией |
| `emojitabbar.h/cpp` | Кастомный QTabBar для эмодзи-панели |
@@ -595,33 +796,98 @@ cmake .. && make -j4
| `invitedialog.h/cpp` | Диалог приглашения пользователя |
| `invite_link.h/cpp` | Логика invite-ссылок |
| `inviteby.h/cpp` | Диалог приглашения по invite-ссылке (отправка через узел) |
| `dminvitedialog.h/cpp` | Выбор канала для приглашения собеседника из DM с сопоставлением результата по request_id |
| `settingsdialog.h/cpp` | Окно настроек |
| `creategroupdialog.h/cpp` | Диалог создания группы |
| `channelsettingsdialog.h/cpp` | Диалог настроек канала |
| `renamedialog.h/cpp` | Диалог переименования |
| `networksettingspage.h/cpp` | Страница сетевых настроек |
| `addressprofiletext.h` | Читаемое представление mapping, доступности входящих и источника NAT-измерения |
| `nodespage.h/cpp` | Таблица узлов + дамп в настройках |
| `statuspage.h/cpp` | Страница статуса (NTP + соединения + живые часы) |
| `databasesettingspage.h/cpp` | Страница обслуживания БД в настройках |
| `storagesettingspage.h/cpp` | Страница настроек хранилища |
| `soundsettingspage.h/cpp` | Страница настроек звука |
| `audiodevicesettingspage.h/cpp` | Страница настроек аудиоустройств |
| `sound_manager.h/cpp` | Управление звуками/уведомлениями |
| `audiorecorder.h/cpp` | Запись голосовых сообщений (захват аудио) |
| `voicemessageencoder.h/cpp` | Кодирование голосовых сообщений (Opus) |
| `sound_manager.h/cpp` | Общий miniaudio-контекст, уведомления/PCM, микширование голоса, маршруты устройств и восстановление |
| `audio_device.h/cpp` | Жизненный цикл miniaudio-устройства, прогресс callbacks, пауза и повтор запуска после сбоя |
| `audio_buffer_tuning.h` | Подбор размера аппаратного аудиобуфера по повторным XRUN с сохранением настройки при reopen |
| `audio_capture.h/cpp` | Совместное использование одного микрофона трансляцией и рацией, подписки PCM и смена профиля захвата |
| `audio_capture_lease.h` | Владение захватом, исключающее одновременную работу publisher, звонка и записи голосового сообщения |
| `audio_event_queue.h` | Ограниченная очередь PCM/команд с несколькими producers и резервом для управляющих событий |
| `audio_frame_ring.h` | Предвыделенное SPSC-кольцо кадров переменной длины под mutex; при переполнении удаляет старейший |
| `voice_audio_io.h/cpp` | Workers захвата/AEC и воспроизведения; упорядочивание PCM/PTT/mute и итоговый render-reference |
| `voice_capture_clock.h` | Непрерывные PTS захваченного PCM по позиции сэмплов с плавной поправкой аппаратного времени |
| `voice_playback_buffer.h` | Адаптивный запас готового PCM: увеличение после недостачи и уменьшение при стабильном выводе |
| `audiorecorder.h/cpp` | Захват голосовых сообщений, worker обработки PCM, компрессор, индикатор уровня и передача записи задаче |
| `voicemessageencoder.h/cpp` | Выбор Opus preset и создание медиа-каталога; кодирование выполняет общий voice_file |
| `voiceplayback.h/cpp` | Воспроизведение голосовых сообщений |
| `media_blocks.h/cpp` | Чтение/сборка фрагментированных медиафайлов |
| `callwindow.h/cpp` | Окно аудио/видеозвонка: управление, выбор камеры, локальное/удалённое видео и статистика |
| `call_audio_engine.h/cpp` | Desktop-контур звонка: захват, VoiceAudioIo, общий выход SoundManager и завершение аудиосессии |
| `call_video_engine.h/cpp` | Desktop-видеозвонок: камера, TX/RX workers, обмен с ядром и показ кадров по аудиочасам |
| `call_video_encoder.h/cpp` | Кодер звонка: согласованный формат, смена битрейта с drain прежнего кодера и подтверждение настройки |
| `call_video_decoder.h/cpp` | FFmpeg-декодер H.264/H.265 с выбором GPU/CPU и сохранением PTS при задержанном выходе |
| `video_capture.h/cpp` | Асинхронный capture-процесс, каталог источников, watchdog и независимое от GUI закрытие |
| `video_capture_worker.cpp` | Камера/экран/окно, преобразование в CPU RGB32 и диагностика этапов аппаратного закрытия |
| `video_capture_source.h` | Контракт backend внутри worker и точка входа для тестовых источников |
| `video_capture_protocol.h` | Поколения, FRAME/ACK, этапы/heartbeat и ограничения IPC видеозахвата |
| `video_capture_buffer.h` | Однокадровый shared-memory буфер согласованной ёмкости до 4096×4096 RGB32 |
| `call_camera_rate.h` | Временное отключение снижения FPS из-за автоэкспозиции V4L2 с восстановлением настройки камеры |
| `call_video_cadence.h` | Отбор исходных кадров под заданный FPS без накопления ошибки дробного периода |
| `call_video_capture_clock.h` | Привязка времени камеры к монотонным часам с коррекцией задержки первого callback |
| `call_video_queue.h` | Ограниченная SPSC-очередь кадров между video workers без mutex и выделений памяти |
| `call_video_wake.h` | Пробуждение video worker по событию или абсолютному монотонному deadline на POSIX/Windows |
| `radio_audio_engine.h/cpp` | Desktop-контур рации: независимые захват/прослушивание, PTT/VAD и подключение к общему выходу |
| `radiopanel.h/cpp` | Панель активной рации: выбор аудиоустройств, VAD, PTT и состояние передачи из ядра |
| `radiosettingspage.h/cpp` | Настройки рации и запись глобальных сочетаний PTT |
| `ptt_hotkey_manager.h/cpp` | Глобальный PTT: физические клавиши Windows/X11, системный портал Wayland |
| `ptt_key_chord.h` | Хранение физических сочетаний с отдельными левыми/правыми модификаторами и запись одновременного нажатия |
| `ptt_portal.h/cpp` | D-Bus-сессия GlobalShortcuts для Wayland, настройка сочетаний и обработка нажатий/отпусканий |
| `imageviewer_window.h/cpp` | Окно просмотра изображений |
| `videoplayer_engine.h/cpp` | Движок декодирования видео |
| `videoplayer_window.h/cpp` | Окно просмотра видео |
| `live_video_encoder.h/cpp` | Общий FFmpeg-кодер live-видео для звонка/трансляции, GPU/CPU, KEY-конфигурация и capture PTS |
| `video_frame_image.h` | Выделение выровненного RGB-буфера FFmpeg и передача владения QImage без копирования |
| `stream_publish_engine.h/cpp` | Публикация камеры/экрана и Opus: workers кодирования, локальный preview и завершение через общий publisher |
| `stream_publish_window.h/cpp` | Настройки и управление трансляцией; закрытие окна сохраняет работающий engine |
| `stream_portal_capture.h/cpp` | Захват экрана Wayland через ScreenCast portal/PipeWire, выбор монитора и режима курсора |
| `stream_screen_cursor.h/cpp`, `stream_screen_cursor_win.cpp` | Наложение системного курсора на кадр выбранного экрана средствами X11/Windows |
| `stream_video_modes.h` | Выбор размеров/FPS камеры и пропорционального масштабирования экрана для трансляции |
| `stream_qp_control.h` | Плавная корректировка потолка QP по фактическому выходному видеобитрейту |
| `stream_sources.h` | Разбор снимка активных источников канала из CHAT_EVT_STREAM_SOURCES |
| `streamplayer_window.h/cpp` | Просмотр live-потока: отдельные audio/video workers, смешивание PCM и синхронизация по часам устройства |
| `streamgrid_window.h/cpp` | Сетка трансляций канала и разворачивание плитки с сохранением плееров; своя плитка использует локальный preview |
| `connmonitorwindow.h/cpp` | Окно мониторинга ETCP-соединений (standalone) |
| `qrcode_utils.h/cpp` | Утилиты для QR-кодов |
| `debug_ui.h` | Отладочный UI |
### Другие поддиректории
- `db/` — SQLite3 amalgamation (`sqlite3.c/h`), `db_manager.h/cpp` (схема: nodes, node_addresses, channels, msg_<channel>, peers_<channel>, local_identity, accounts, ui_state)
- `transport/` — интеграция с uTun: `gui_bridge.h/gui_bridge_impl.cpp` (Qt signal-based обмен), `node_config.h/cpp` (конфиг узла), `config_updater.h/cpp` (правка конфига), `utun_node.h/cpp` (обёртка узла), `miniaudio_impl.c` (single-header miniaudio в отдельной единице трансляции). Chat-логика (`chat_core`, `chat_sync` и т.д.) компилируется напрямую из `src/chat/`, роутинг — из `src/routing_layer/` (см. `libutun/CMakeLists.txt`)
- `db/` — `db_manager.h/cpp`: доступ GUI к данным nodes, channels, msg_<channel>, peers_<channel> и состоянию интерфейса;
копия `db/sqlite3.c/h` не используется текущей CMake-целью, SQLite берётся из `lib/`
- `transport/` — интеграция GUI с ядром; файлы перечислены ниже
- `src/avatars/` — `avatarmanager.h/cpp`: загрузка/публикация аватаров участников через member_files, подписанные ссылки и очередь передач;
`avatarcache.h/cpp`: дисковый кеш, подготовка изображений и очистка; `avatarcrop.h/cpp`: выбор области;
`avatargallery.h/cpp`: просмотр аватаров пользователя; `groupavatarmanager.h/cpp`: подготовка и кеш подписанных аватарок каналов
- `src/member_files/` — `browser.h/cpp`: браузер серверных файлов группы; `batch.h/cpp`: последовательные операции над файлами/деревьями,
фоновый локальный обход, загрузка/скачивание и отмена
- `libutun/CMakeLists.txt` — состав и зависимости CMake-сборки общего ядра из `src/` и `lib/`
- `CMakeLists.txt` — приложение vibechat, Qt-зависимости, ресурсы и цели GUI-тестов
- `tests/` — проверки аудиотракта, PTT, видеозвонка, захвата камеры/экрана, трансляций, файлового браузера и GUI-компонентов
- `resources/` — `bg.jpg`, `chatgui.qrc` (встраивает 5 TGS в бинарник), `animations/*.tgs`
- `zxing-cpp/` — встроенная библиотека QR-кодов; `third_party/qhotkey/` — исходники QHotkey
### Интеграция с ядром (transport/)
| Файл | Назначение |
|------|-----------|
| `gui_bridge.h` / `gui_bridge_impl.cpp` | Команды GUI → uasync и события ядра → Qt-сигналы |
| `utun_node.h/cpp` | Запуск и остановка ядра/чата в выделенном uasync-потоке |
| `node_config.h/cpp` | Загрузка и сохранение конфигурации узла |
| `config_updater.h/cpp` | Изменение настроек в конфиге |
| `miniaudio_impl.c` | Реализация single-header miniaudio в отдельной единице трансляции |
| `audio_diagnostics.h/cpp` | Диагностика этапов аудио и событий backend; записывает метаданные без PCM |
| `stream_bridge.h/cpp` | Потокобезопасный мост к общим publisher/viewers: session IDs, каталог источников, запросы батчей и пробуждение workers |
### Система анимированных эмодзи
@@ -715,18 +981,33 @@ void lottie_animation_destroy(Lottie_Animation *anim);
---
## Key Documentation Files
- `/doc/etcp_protocol.txt` - ETCP протокол (формат кодограмм, ACK, handshake, keepalive)
- `/doc/etcp_arch.md` - ETCP архитектура
- `/doc/etcp_config.txt` - Конфигурация ETCP
- `/doc/etcp_router_arch.md` - ETCP роутер архитектура
- `/doc/route_p2pconn.txt` - Route peer-to-peer соединения
- `/src/route_bgp.txt` - BGP обмен маршрутами (дизайн-документ)
- `/doc/chat_join_test.md` - ТЗ теста join-протокола (chat_join + дерево приглашений)
- `/doc/chat_join_test_tasks.md` - Список задач по тесту join (текущий статус, пошагово)
- `doc/service_lifecycle.md` — ядро, независимые сервисы, владение ресурсами и остановка
- `doc/node_snapshot.md` — подписанная запись узла, timestamp, SQLite и обновление NCD
- `doc/etcp_protocol.txt` — ETCP: кодограммы, ACK, handshake, keepalive
- `doc/etcp_arch.md` — архитектура ETCP
- `doc/etcp_router_arch.md` — архитектура маршрутизатора
- `src/chat/chat_join.h` — нормативный протокол добавления участника
- `src/routing_layer/topo_group.h` — протокол групповой сессии и критерий READY
- `tests/test_chat_join_e2e.c`, `tests/test_topo_recovery.c`, `tests/test_services.c` — проверки join, recovery и жизненного цикла
- `doc/dm_arch.md`, `doc/chat_call_arch.md` — личные сообщения и звонки
- `doc/call_video.txt` — видеотрек звонка: возможности кодеков, транспорт, битрейт, аудиочасы и показ кадров
- `doc/stream.txt` — трансляции: RS-пачки, выдачи/relay, выбор поставщиков, медиакурсоры и платформенные плееры
- `doc/stun_nat.md`, `doc/nat_detection.txt` — STUN-измерения и определение доступности рабочих UDP-сокетов
- `doc/member_files.txt` — файловое хранилище участников, права, wire-команды и передачи
- `doc/group_avatar.txt` — подписанная аватарка канала, хранение и репликация
- `doc/encrypted_attachments.md` — контейнер группового вложения, запросы ключа и ручная выдача доступа
- `doc/pm_invites.md`, `doc/message_links.md` — приглашения из личной беседы и ссылки внутри сообщений
- `doc/proxy_protocol.md` — TCP/UDP/ICMP-прокси, управление окнами, half-close и проверки
- `doc/lwip_nuances.md` — особенности адаптированного lwIP TCP-стека
- `doc/linux_audio_recovery.md` — диагностика аудиотракта Linux, контракты владения и восстановление устройств
- `src/media_delivery/file_transfer.h`, `src/dm/dm_media.h` — контракты передачи файлов и E2E-вложений DM
- `src/call/call_audio.h`, `src/radio/radio_audio.h` — API общего голосового стека и правила потоков
- `tools/chatcli_commands.txt` — команды headless CLI, в том числе DM, звонки и рация
## Список задач по проекту
Список задач — `/doc/tasks.md` (текущая работа, берём по одной задаче сверху).
Список задач — `doc/tasks.md` относительно корня репозитория (текущая работа, берём по одной задаче сверху).
При нахождении попутных багов/fail/флаков тестов добавляем задачу (либо фиксим сразу если баг простой).
Как сделали - помечаем [+] выполнено.
@@ -734,18 +1015,47 @@ void lottie_animation_destroy(Lottie_Animation *anim);
**Расположение:** `tools/chatgui-android/`
Android-версия чатгуи — P2P чат на STCP (TCP), UI на Jetpack Compose (Kotlin).
C-ядро: `libutun_lite` (выборочная компиляция нужных .c из `lib/` и `src/`).
Android-версия чатгуи — P2P чат на общем ETCP/STCP-ядре, UI на Jetpack Compose (Kotlin).
C-библиотека `utun_lite` собирает `lib/` и `src/` по `libutun_lite/utun_sources.cmake`;
`instance_lite` запускает ядро и чат в отдельном потоке, без UTUN-сервиса.
Сборка: CMake (headless, Linux) + Gradle/NDK (Android APK).
- 'fw' - собрать и обновить chatgui-android на всех подключенных телефонах (clean + сборка + install)
**Подробная инструкция:** `tools/chatgui-android/AGENTS.md`
**Chat-модули:** все файлы из `src/chat/` (описаны выше в секции «Chat») компилируются в `libutun_lite`.
### Основные файлы native-слоя
Пути относительны к `tools/chatgui-android/`; UI и Android-сервисы описаны в локальном `AGENTS.md`.
| Файл | Назначение |
|------|-----------|
| `libutun_lite/utun_sources.cmake` | Общий список исходников ядра для Android и headless |
| `libutun_lite/CMakeLists.txt` | Сборка native-библиотеки и зависимостей |
| `libutun_lite/instance_lite.c/h` | Запуск ядра/чата по INI-тексту и управление отдельным uasync-потоком |
| `libutun_lite/utun_config_api.c/h` | Провайдер конфигурации: callbacks Kotlin и значения для native-слоя |
| `libutun_lite/standby.c/h` | Фоновый duty-cycle, таймеры активных интервалов и ожидание пробуждения |
| `libutun_lite/invite_link_c.c/h` | Старая копия C-кодека; .c исключён из UTUN_SOURCES, рабочий код — src/chat/invite_link.c/h |
| `libutun_lite/attachment_sender.c/h` | Отправка файлов в канал через chat_msg_submit и канальный медиа-индекс |
| `libutun_lite/photo_sender.c/h` | Отправка фотографий в канал с MIME-типом и размерами изображения |
| `libutun_lite/video_sender.c/h` | Отправка видео через общий механизм подготовки вложений |
| `libutun_lite/voice_recorder.c/h` | Накопление PCM записи, компрессор и отправка голоса через общий attachment_send |
| `libutun_lite/stream_bridge.c/h` | Android-мост к publisher/viewers: session IDs, готовые access units/Opus и ограниченные батчи треков |
| `jni_bridge/android_jni_bridge.c/h` | JNI-команды и callbacks между Kotlin и C-ядром, события и аудио API |
| `jni_bridge/android_call_output_jni.c` | Вывод PCM звонка через AAudio с аппаратным тактированием и снимками позиции устройства |
| `jni_bridge/android_call_video_jni.c` | JNI видеозвонка: capabilities/формат, обмен кадрами с call_video_port, playout и поворот YUV |
| `jni_bridge/android_stream_jni.c` | JNI трансляций: publisher/viewer API, Opus/SoundTouch, готовый PCM и часы воспроизведения |
| `jni_bridge/android_udp_log.c/h` | Потокобезопасный буфер UDP-логов с flush-таймером в потоке ядра |
| `headless/headless_main.c` | Отдельный каркас control-loop; сам не запускает ядро/чат |
| `headless/headless_control.c/h` | Каркас control-сокета; часть команд — заглушки, рабочий API — src/chat/chat_headless_control.c/h |
| `app/src/main/cpp/CMakeLists.txt` | NDK-сборка библиотеки приложения |
| `libutun_lite/tests/test_standby.c` | Проверка duty-cycle и жизненного цикла standby |
## Runtime
- Запуск utun от root (для tun): `/home/vnc1/proj/utun3/utun_start.sh`
- Стоп utun: `sudo /home/vnc1/proj/utun3/utun_stop1.sh`
- Логи: `utun.log` (stdout), `utun_err.log` (stderr)
- После autotools-сборки бинарник — `src/utun`. Запуск из корня с TUN: `sudo ./src/utun -f -c utun.cfg`.
- Старый `utun_start.sh` ожидает `./utun` в корне. `utun_stop.sh` делает `killall -9 utun`, а не штатную остановку одного экземпляра.
- `-f` оставляет процесс на переднем плане; остановка — SIGINT/SIGTERM. Пути конфигурации, PID и лога задаются через `-c`, `-p`, `-l`.
- `utun_start.sh` перенаправляет stdout в `utun.log`, stderr в `utun_err.log`.
- Тестовые логи: `tests/logs/`
## Git Conventions
@@ -756,19 +1066,19 @@ C-ядро: `libutun_lite` (выборочная компиляция нужны
## Quick Start for New Features
1. Add new source file to `src/Makefile.am` under `utun_SOURCES`
2. Add test file to `tests/Makefile.am` under `check_PROGRAMS`
2. Add test target and its sources/dependencies to `tests/Makefile.am` under `check_PROGRAMS`
3. Use existing patterns from similar modules
5. Run `./check.sh` after changes
4. Run `./check.sh` after changes
5. Commit with descriptive message in appropriate language
## chatgui: отправка сообщений через xdotool
1. **Запуск:** `setsid env DISPLAY=:1.0 QT_ACCESSIBILITY=1 ./chatgui & disown` (иначе SIGTERM убьёт процесс при таймауте bash)
2. **Окно:** `0x4600006 "Chat"` (WM_CLASS "chatgui"), 900×600. Не путать с `0x4800001` (10×10, временное)
3. **Фокус:** клик в область InputBar (x=400, y=570 относительно окна) перед вводом
4. **Отправка:** `xdotool type --window WID "text"` + `xdotool key --window WID Return`
5. **Проверка:** `sqlite3 chats.db "SELECT ... FROM msg_ch_GENERAL"` — сообщения в per-channel таблицах
6. **MCP computer use** не видит chatgui — нужен `qt5-at-spi` bridge (нет в репах, ставить из исходников Qt)
1. **Запуск:** из каталога сборки `setsid env QT_ACCESSIBILITY=1 ./vibechat & disown` с DISPLAY текущей X11-сессии.
2. **Окно:** найти актуальный ID через `xdotool search --onlyvisible --class vibechat`; ID и размеры окна меняются между запусками.
3. **Фокус:** активировать найденное окно и выбрать InputBar; координаты определять по текущему расположению интерфейса.
4. **Отправка:** `xdotool type --window WID "text"` + `xdotool key --window WID Return`, где WID заменён найденным ID.
5. **Проверка:** через `chats.db` из каталога `db_path`; таблицы сообщений называются `msg_<числовой channel_id>`.
6. Доступность UI-автоматизации зависит от текущей X11/Wayland-сессии и настроек Qt accessibility; старые ID окон и DISPLAY не переносить.
---
Эта инструкция имеет приоритет над инструкцией opencode.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="ua.cn.stu.navigation">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
tools:ignore="CoarseFineLocation" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Navigation">
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".ble.BluetoothLeService"
android:enabled="true" />
</application>
</manifest>
Binary file not shown.
+99
View File
@@ -0,0 +1,99 @@
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.18.1)
# Declares and names the project.
project("bt_drv")
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
bt_drv
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
bt_drv.c
ble_tcp.c
ble_eth.c
eth_mem.c
eth_router.c
eth_nat.c
eth_queue.c
xlib.c
settings.c
images.c
# LWIP
# lwip/api/api_lib.c
#// lwip/api/api_msg.c
#// lwip/api/err.c
#// lwip/api/if_api.c
#// lwip/api/tcpip.c
lwip/dnsproxy.c
lwip/dhcp_server.c
lwip/net_raw.c
lwip/net_topology.c
lwip/lwip.c
lwip/eth_router_if_lwip.c
lwip/core/def.c
lwip/core/inet_chksum.c
lwip/core/init.c
lwip/core/ip.c
lwip/core/mem.c
lwip/core/memp.c
lwip/core/netif.c
lwip/core/pbuf.c
lwip/core/raw.c
lwip/core/stats.c
lwip/core/sys.c
lwip/core/tcp.c
lwip/core/tcp_in.c
lwip/core/tcp_out.c
lwip/core/timeouts.c
lwip/core/udp.c
lwip/core/ipv4/icmp.c
lwip/core/ipv4/ip4.c
lwip/core/ipv4/ip4_addr.c
lwip/core/ipv4/ip4_frag.c
lwip/core/ipv4/etharp.c
lwip/netif/ethernet.c
)
include_directories(
.
lwip
lwip/include
)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
bt_drv
# Links the target library to the log library
# included in the NDK.
${log-lib} )
+190
View File
@@ -0,0 +1,190 @@
#include <stdint.h>
#include <string.h>
#include <pthread.h>
#include "xlib.h"
#include "ble_eth.h"
#include "eth_mem.h"
#include "eth_router.h"
#include "ble_tcp.h"
//#define BLE_FLOOD_TEST
// модуль разобрки-сборки кодограмм на фрагменты. Работает вместе с ble_tcp и с ble_link
/* Формат посылки:
Кодограмма разбиватеся на куски. К каждому куску в начале добавляется один байт.
Формат байта: байт0 биты 6,7 - тип посылки. Биты 0-5 будут перезаписаны при передаче.
bit7:6 - тип кодограммы:
00 (0x00) - промежуточный блок кодограммы
01 (0x40) - первый блок кодограммы
10 (0x80) - последний блок кодограммы
11 (0xC0) - вся кодограмма в одном фрагменте
*/
struct BLE_ETH_STATS ble_eth_stats;
static struct ETH_PBUF* current_tx_block=NULL;
static uint8_t eth_rst_req_rx;
static uint8_t tx_rst=0;
void gatt_eth_reset() {
eth_rst_req_rx=1;
tx_rst=1;
}
static struct ETH_PBUF* rx_pbuf=NULL;
static uint16_t rx_ptr;
static uint8_t rx_prev_seq;
static uint8_t rx_seq_err;
int process_dgram_asm(uint8_t* data, uint16_t len) {// BLE to ETH_router
ble_eth_stats.rx_chunks++;
if (len<2) { ble_eth_stats.rx_too_short_chunk++; return 0; }
// if (eth_netif_array[BLE_NETIF_ID].input_queue_len>IN_BLE_NETIF_QLEN_THR) { ble_eth_stats.rx_qpause++; return -1; }// очередь заполнена, временно не принимаем новое (loopback test mode)
// если очередь полная, то приостановим поток
if (eth_rst_req_rx) {
eth_rst_req_rx=0;
if (rx_pbuf) {
eth_pbuf_free_request(rx_pbuf);
rx_pbuf=NULL;
}
rx_ptr=0;
}
uint8_t dg_type=data[0]&0x0C0;
uint8_t dg_seq=data[0]&0x03F;
if (dg_type & 0x40) {// first block
rx_ptr=0;
rx_seq_err=0;
rx_prev_seq=(dg_seq-1)&0x03F;
if (rx_pbuf==NULL) rx_pbuf=eth_pbuf_alloc(&xeth_pbuf_ctrl, NULL);
if (rx_pbuf==NULL) { ble_eth_stats.rx_pbuf_alloc_err++; return -1; }
}
if (rx_pbuf!=NULL) {
rx_prev_seq=(rx_prev_seq+1)&0x3F;
if (rx_prev_seq!=dg_seq || rx_seq_err) {
ble_eth_stats.rx_seqerr++;
eth_pbuf_free_request(rx_pbuf);
rx_pbuf=NULL;
return 0;
}
len--;
if (rx_ptr+len<=ETH_MEM_BUF_SIZE) {
memcpy((uint8_t*)rx_pbuf->pbuf.payload+rx_ptr, data+1, len);
rx_ptr+=len;
if (dg_type & 0x080) {// last block
rx_pbuf->pbuf.len=rx_ptr;
rx_pbuf->pbuf.tot_len=rx_ptr;
rx_pbuf->pbuf.if_idx=BLE_NETIF_ID;
if (rx_ptr>=14) { ble_eth_stats.rx_dgrams++; eth_add_packet_to_router_queue(rx_pbuf); }
else { ble_eth_stats.rx_too_short_dgram++; eth_pbuf_free_request(rx_pbuf); }
rx_pbuf=NULL;
}
}
else {// invalid block
ble_eth_stats.rx_oversize++;
eth_pbuf_free_request(rx_pbuf);
rx_pbuf=NULL;
}
}
return 0;
}
#define MAX_CHUNK_LEN 167//239
static uint16_t chunk_len;// for BLE - current chunk length
static uint16_t tx_ptr;// pointer for chunks
static int cbk_pending=0;
int get_next_chunk(uint8_t* chunk_for_tx) {// взять новый блок. Или NULL если блока нет (если блока нет - будет вызван коллбэк)
if (tx_rst) {
tx_rst=0;
tx_ptr=0;
}
#ifdef BLE_FLOOD_TEST
ble_eth_stats.tx_chunks++;
chunk_for_tx[0]=0xC0;
return 240;// for test
#endif
if (cbk_pending) return 0;
if (current_tx_block==NULL) {
cbk_pending=1;
struct ETH_PBUF* tb=eth_get_packet(&eth_netif_array[BLE_NETIF_ID]);
if (tb==NULL) {
return 0;// waiting for callback
} else { current_tx_block=tb; cbk_pending=0; }
}
uint8_t pkt_sent;// 0 - no data; 1 - send in progress, 2 - send finished
int32_t len=current_tx_block->pbuf.len-tx_ptr;
if (tx_ptr==0) chunk_for_tx[1]=0x40; else chunk_for_tx[1]=0;
if (len>MAX_CHUNK_LEN) { len=MAX_CHUNK_LEN; pkt_sent=0; } else { chunk_for_tx[1]|=0x80; pkt_sent=1; }
chunk_len=len+2;
memcpy(&chunk_for_tx[2], (uint8_t*)(current_tx_block->pbuf.payload)+tx_ptr, len);
tx_ptr+=len;
if (pkt_sent) {// последний блок скопирован в chunk_for_tx. пакат можно освобождать
ble_eth_stats.tx_dgrams++;
eth_pbuf_free_request(current_tx_block);
current_tx_block=NULL;
tx_ptr=0;
}
ble_eth_stats.tx_chunks++;
return chunk_len;
}
void next_chunk_avail();
static void callback_from_bridge(struct ETH_PBUF* block, struct ETH_NETIF* enetif) {// появился пакет на передачу
current_tx_block=block;
cbk_pending=0;
next_chunk_avail();
}
void ble_callback_qlen(struct ETH_NETIF* netif) {
if (netif->input_queue_len<IN_BLE_NETIF_QLEN_THR) {// обновилась очередь в роутере - позволяет забрать пакет
notify_ble_out_queue();
}
}
_Noreturn void tcp_test_Task(void * arg) {
while(1) {
struct ETH_PBUF* block=eth_pbuf_alloc(&xeth_pbuf_ctrl, NULL);
if (block) {
memset(block->pbuf.payload, 0,1000);
char* d=(char*)block->pbuf.payload;
d[0]=1;
d[1]=2;
d[2]=3;
d[3]=4;
d[4]=5;
d[5]=6;
block->pbuf.len=230;
block->pbuf.tot_len=230;
block->pbuf.if_idx=LWIP_NETIF_ID;
eth_add_packet_to_router_queue(block);
}
usleep(1000*500);
}
}
pthread_t ttHandle;
void eth_ble_if_init() {
eth_netif_array[BLE_NETIF_ID].callback_fn=callback_from_bridge;// инициализируем callback (пакет готов)
eth_netif_array[BLE_NETIF_ID].q_output_len_max=BLE_NETIF_QLEN;
eth_netif_array[BLE_NETIF_ID].q_update_cbk=ble_callback_qlen;
eth_netif_array[BLE_NETIF_ID].if_up=1;
// TaskCreate (tcp_test_Task, &ttHandle);
eth_netif_array[TEST_NETIF_ID].q_output_len_max=BLE_NETIF_QLEN;
eth_netif_array[TEST_NETIF_ID].if_up=1;
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <stdint.h>
#define MAX_CHUNK_LEN 167
struct BLE_ETH_STATS {
uint32_t tx_chunks;
uint32_t rx_chunks;
uint32_t tx_dgrams;
uint32_t rx_dgrams;
uint32_t rx_too_short_chunk;
uint32_t rx_too_short_dgram;
uint32_t rx_oversize;
uint32_t rx_pbuf_alloc_err;
uint32_t rx_qpause;
uint32_t rx_seqerr;
uint32_t d1;
uint32_t d2;
uint32_t d3;
uint32_t d4;
};
extern struct BLE_ETH_STATS ble_eth_stats;
int get_next_chunk(uint8_t* chunk_for_tx);
int process_dgram_asm(uint8_t* data, uint16_t len);
void eth_ble_if_init();
void gatt_eth_reset();
+196
View File
@@ -0,0 +1,196 @@
#include <jni.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
#include "ble_tcp.h"
#include "xlib.h"
#include "bt_drv.h"
#include "eth_mem.h"
#include "eth_router.h"
#include "ble_eth.h"
// модуль обеспечивающий ретрансмиссии, буферизацию, контроль потока для GATT посылок.
#define ACK_MIN_INTERVAL 25// mS. на эту величину может задерживаться отправка ACK
//#define print_pkt_body
static uint32_t last_ack_time;
static uint8_t ack_sent_value;
static uint8_t snd_blk_len;
static uint8_t snd_blk[MAX_CHUNK_LEN+2];
static struct itimerspec trigger;
static timer_t timerid;
static uint8_t ack_notify_request;
#define TMR_CHECK_TXBUF_PERIOD 100
//static TimerHandle_t xTcpTimer;
static struct NHandle_t tNotifyHandle;
pthread_t tHandle;
pthread_t tHandle1;
sem_t tcp_tx_sem;
sem_t tcp_rx_sem;
#define TX_LOCK sem_wait(&tcp_tx_sem)
#define TX_UNLOCK sem_post(&tcp_tx_sem)
#define RX_LOCK sem_wait(&tcp_rx_sem)
#define RX_UNLOCK sem_post(&tcp_rx_sem)
#define taskNOTIFY_ACK_UPDATE 1// очередь передачи
#define taskNOTIFY_NEXT_CHUNK_AVAIL 2
#define taskNOTIFY_NEXT_CHUNK_FOR_TX_AVAIL 4
#define taskNOTIFY_BLE_TX_COMPLETE 8
#define taskNOTIFY_nACK_UPDATE 16// приемная очередь
#define taskNOTIFY_TMR_IDLE 64
#define taskNOTIFY_PUSH_RECVD 256
struct BLE_TCP_STATS ble_tcp_stats;
struct BLE_TCP ble_tcp;
uint8_t tx_index_blk;// ячейка ожидающая передачу
uint8_t tx_push_ptr_blk;// ячейка ожидающая добавление элемента
static uint32_t tx_last_time;// ячейка ожидающая добавление элемента
uint8_t rx_nack_blk;// циклический номер блока, ожидающего приём
void gatt_conn_reset() {
TX_LOCK;
RX_LOCK;
ble_tcp.ble_tx_busy=0;
ble_tcp_stats.rst_cnt++;
rx_nack_blk=1;
tx_index_blk=0;
tx_push_ptr_blk=0;
snd_blk_len=0;
gatt_eth_reset();
TNotifyAdd( &tNotifyHandle, taskNOTIFY_BLE_TX_COMPLETE);
RX_UNLOCK;
TX_UNLOCK;
}
void notify_ble_out_queue() {// callback: обновилась очередь ETH / ble_if
TNotifyAdd(&tNotifyHandle, taskNOTIFY_PUSH_RECVD);
}
void process_gatt_data(uint8_t* data, uint16_t len) {
ble_tcp_stats.rx_raw++;
if (len<1) { ble_tcp_stats.rx_empty_dg++; return; }
ble_tcp_stats.rx_bytes+=len;
#ifdef print_pkt_body
if (len==1) print_log("Recv %d bytes [%02x]", len, data[0]);
else print_log("Recv %d bytes [%02x %02x]", len, data[0], data[1]);
#endif
TX_LOCK;
rx_nack_blk=data[0]&0x3F;
TNotifyAdd( &tNotifyHandle, taskNOTIFY_nACK_UPDATE );
TX_UNLOCK;
if (len>1) {
RX_LOCK;
process_dgram_asm(data+1, len-1);
RX_UNLOCK;
}
}
void next_chunk_avail() {
TNotifyAdd( &tNotifyHandle, taskNOTIFY_NEXT_CHUNK_AVAIL );
}
void ble_tx_complete(int status) {
ble_tcp.ble_tx_busy=0;
TNotifyAdd( &tNotifyHandle, taskNOTIFY_BLE_TX_COMPLETE );// ззавершена передача. можно затолкать в буфер передачи еще
}
static int ble_gatt_trysend(uint8_t * data, uint16_t len) {
if (ble_connection_status!=2) return -3;// not ready for send
if (ble_tcp.ble_tx_busy) return -1;
ble_tcp.ble_tx_busy=1;
int ret=bt_send(data, len);// status: 1 - all ok, 0 - error
if (ret!=1) { ble_tcp.ble_tx_busy=0; return -2; }
ble_tcp_stats.tx_raw++;
#ifdef print_pkt_body
if (len==1) print_log("Send %d bytes [%02x]", len, data[0]);
else print_log("Send %d bytes [%02x %02x]", len, data[0], data[1]);
#endif
return 0;
}
// байт 1 (или 1+2) - rx ack / sack
_Noreturn void BLE_TCP_Task(void * arg) {
send_thread_register();// зарегистрировать в java VM этот поток для возможности совершать вызовы
while (1) {
uint32_t res=TNotifyWait( &tNotifyHandle );
// попробуем передать что накопилось
if ((res & (taskNOTIFY_BLE_TX_COMPLETE | taskNOTIFY_NEXT_CHUNK_AVAIL | taskNOTIFY_nACK_UPDATE | taskNOTIFY_TMR_IDLE)) && ble_tcp.ble_tx_busy==0) {
dbg[0]++;
TX_LOCK;
int idx=tx_index_blk;
int len=snd_blk_len;
if (len==0) {
len=get_next_chunk(&snd_blk[0]);
snd_blk_len=len;
}
if (len || (ack_notify_request && ack_sent_value!=rx_nack_blk )) {// шлем если есть что слать, либо пора отправить обновление по ACK
uint32_t ack=rx_nack_blk;
snd_blk[0]=ack;
if (len==0) len=1;
else snd_blk[1]=(idx&0x3F)|(snd_blk[1] & 0xC0);// сохраняем биты признака начала-конца кодограммы для разобрщика кодограмм
// 167 = 5 (800) *9=1503 (169 bytes max incl. headers)
int ret=ble_gatt_trysend(&snd_blk[0], len);// ack + dgram
if (ret==0) {
snd_blk_len=0;
ble_tcp_stats.tx_bytes+=len;
ble_tcp_stats.tx_blocks++;
ack_sent_value=ack;
ack_notify_request=0;
timer_settime(timerid, 0, &trigger, NULL);
tx_index_blk=(idx+1)&0x3F;
}
}
TX_UNLOCK;
}
}
}
static void tcp_tmr( void* arg ) {
TX_LOCK;
ack_notify_request=1;
TX_UNLOCK;
TNotifyAdd( &tNotifyHandle, taskNOTIFY_TMR_IDLE);// no activity. for timed-out retransmit
}
void ble_tcp_init() {
sem_init(&tcp_tx_sem, 0, 1);
sem_init(&tcp_rx_sem, 0, 1);
tx_last_time=xTaskGetTickCount();
TaskCreate (BLE_TCP_Task, &tHandle);
TNotifyCreate(&tNotifyHandle);
TNotifyAdd( &tNotifyHandle, taskNOTIFY_ACK_UPDATE);
struct sigevent sev;
memset(&sev, 0, sizeof(struct sigevent));
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = &tcp_tmr;
memset(&trigger, 0, sizeof(struct itimerspec));
timer_create(CLOCK_REALTIME, &sev, &timerid);
trigger.it_value.tv_sec = ACK_MIN_INTERVAL/1000000;
trigger.it_value.tv_nsec = ACK_MIN_INTERVAL*1000000;
timer_settime(timerid, 0, &trigger, NULL);
}
+57
View File
@@ -0,0 +1,57 @@
struct BLE_TCP_STATS {
uint32_t tx_raw;
uint32_t rx_raw;
uint32_t tx_blocks;
uint32_t rx_blocks;
uint32_t tx_err;
uint32_t tx_ack_err;
uint32_t tx_sack_err;
uint32_t tx_ack_negdist_err;
uint32_t tx_ack_toomuch_err;
uint32_t ack_upd;
uint32_t rx_empty_dg;
uint32_t rx_only_ack;
uint32_t rx_seq_err;
uint32_t rx_dup_ack;
uint32_t rx_neg_ack;
uint32_t rx_duplicates;
uint32_t rx_detected_retransmit_jumps;
uint32_t rx_detected_packet_loss_single;
uint32_t rx_detected_packet_loss_multiple;
uint32_t rx_detected_incorrect_jumps;
uint32_t rst_cnt;
uint32_t rstreq_cnt;
uint32_t rxasm_throttle;
uint32_t rxasm_try;
uint32_t tx_bytes;
uint32_t rx_bytes;
uint32_t d1;
uint32_t d2;
uint32_t d3;
uint32_t d4;
};
extern struct BLE_TCP_STATS ble_tcp_stats;
struct BLE_TCP {
uint32_t ble_tx_busy;
};
extern struct BLE_TCP ble_tcp;
extern uint8_t tx_busy_mask[8];
extern uint8_t rx_ready_mask[8];
extern uint8_t rx_nack_blk;
extern uint8_t rx_last_recvd_blk;
extern uint8_t tx_ack_blk;// следующая после подтвержденной ячейка (т.е. начиная с которой надо передавать)
extern uint8_t tx_index_blk;// ячейка ожидающая передачу
extern uint8_t tx_push_ptr_blk;// ячейка ожидающая добавление элемента
void ble_tcp_init();
void notify_ble_out_queue();//
void ble_tx_complete(int status);
void process_gatt_data(uint8_t* data, uint16_t len);
void gatt_conn_reset();
+355
View File
@@ -0,0 +1,355 @@
#include <jni.h>
#include "bt_drv.h"
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>
#include <semaphore.h>
#include <stdatomic.h>
#include "xlib.h"
#include "ble_tcp.h"
#include "eth_mem.h"
#include "eth_router.h"
#include "ble_eth.h"
#include "lwip/lwip.h"
#include "eth_nat.h"
#include "lwip/net_topology.h"
//#include "lwip/opt.h"
//#include "lwip/mem.h"
//#include "lwip/memp.h"
//#include "lwip/netif.h"
//#include "lwip/init.h"
int dbg_scr_num=0;
// ====================================== startup =========================
JavaVM* gJvm = NULL;
jobject bleservice;
jclass bleserv;
jclass bleserv1;
JNIEnv* send_env;
JNIEnv* status_upd_env;
jmethodID send_method;
jmethodID frame_method;
jmethodID status_upd_method;
volatile int ble_connection_status=0;// 2 - connection up.
int bt_send(uint8_t* dgr, uint16_t dglen) {
dbg[3]++;
JNIEnv *env=send_env;
jbyteArray dgram=(*env)->NewByteArray(env, dglen);
if (dgram == NULL) return -1;
(*env)->SetByteArrayRegion (env, dgram, 0, dglen, dgr);
// jbyteArray bytes = (*env)->GetObjectField(env, obj, sendId)
// jbyte *stateJava = (*env)->GetByteArrayElements(env, dgram, NULL);
// if (stateJava == NULL) return -1;
// memcpy(stateJava, dgr, dglen);
int ret=-1;
if (send_method) ret=(*env)->CallStaticIntMethod(env, bleserv, send_method, dgram);
(*env)->DeleteLocalRef(env, dgram);
// print_log("[BLE] send dgram %d", ret);
return ret;
}
jbyteArray jname;
jbyteArray jval;
static void status_upd(int p, char* name, char* val) {
JNIEnv *env=status_upd_env;
jbyteArray jname=(*env)->NewByteArray(env, strlen(name));
if (jname == NULL) return;
(*env)->SetByteArrayRegion (env, jname, 0, strlen(name), name);
jbyteArray jval=(*env)->NewByteArray(env, strlen(val));
if (jval == NULL) return;
(*env)->SetByteArrayRegion (env, jval, 0, strlen(val), val);
if (status_upd_method) (*env)->CallStaticVoidMethod(env, bleserv1, status_upd_method, p, jname, jval);
(*env)->DeleteLocalRef(env, jname);
(*env)->DeleteLocalRef(env, jval);
}
void status_upd_thread_register() {
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6; // choose your JNI version
args.name = NULL;
args.group = NULL;
jint ret=(*gJvm)->AttachCurrentThread(gJvm, &status_upd_env, &args);
if (ret) return;
}
void send_thread_register() {
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6; // choose your JNI version
args.name = NULL;
args.group = NULL;
jint ret=(*gJvm)->AttachCurrentThread(gJvm, &send_env, &args);
if (ret) return;
}
void status_upd1(int i, char* b, uint32_t c) {
char str[100];
sprintf(str, "%d",c);
status_upd(i, b, str);
}
uint32_t tx_hist[16];
uint32_t rx_hist[16];
uint32_t htime[16];
uint8_t histptr;
pthread_t thr;
_Noreturn void status_thread(void* arg) {
status_upd_thread_register();
while(1) {
int p=histptr&15;
tx_hist[p]=ble_tcp_stats.tx_bytes;
rx_hist[p]=ble_tcp_stats.rx_bytes;
htime[p]=xTaskGetTickCount();
int tx_spd=(tx_hist[p]-tx_hist[(p-10)&15])*1000/(htime[p]-htime[(p-10)&15]);
int rx_spd=(rx_hist[p]-rx_hist[(p-10)&15])*1000/(htime[p]-htime[(p-10)&15]);
p++;
histptr=p&15;
dbg[1]=(dbg[1]+1)%170;
int i = 1;
if (dbg_scr_num==0) {
status_upd1(i++, "dbg[0]", dbg[0]);
status_upd1(i++, "dbg[1]", dbg[1]);
status_upd1(i++, "dbg[2]", dbg[2]);
status_upd1(i++, "dbg[3]", dbg[3]);
status_upd1(i++, "dbg[4]", dbg[4]);
status_upd1(i++, "dbg[5]", dbg[5]);
status_upd1(i++, "dbg[6]", dbg[6]);
status_upd1(i++, "dbg[7]", dbg[7]);
status_upd1(i++, "dbg[8]", dbg[8]);
status_upd1(i++, "dbg[9]", dbg[9]);
status_upd1(i++, "dbg[10]", dbg[10]);
status_upd1(i++, "tx_chunks", ble_eth_stats.tx_chunks);
status_upd1(i++, "rx_chunks", ble_eth_stats.rx_chunks);
status_upd1(i++, "tx_dgrams", ble_eth_stats.tx_dgrams);
status_upd1(i++, "rx_dgrams", ble_eth_stats.rx_dgrams);
status_upd1(i++, "rx_qpause", ble_eth_stats.rx_qpause);
status_upd1(i++, "rx_seqerr", ble_eth_stats.rx_seqerr);
status_upd1(i++, "tx_spd", tx_spd);
status_upd1(i++, "rx_spd", rx_spd);
}
if (dbg_scr_num==1) {
status_upd1(i++, "ble_conn_status", ble_connection_status);
status_upd1(i++, "BLEif_dg_in", eth_netif_array[BLE_NETIF_ID].dgrams_in);
status_upd1(i++, "BLEif_dg_lost", eth_netif_array[BLE_NETIF_ID].dgrams_lost);
status_upd1(i++, "BLEif_dg_out", eth_netif_array[BLE_NETIF_ID].dgrams_out);
status_upd1(i++, "BLEif_dg_outqlen", eth_netif_array[BLE_NETIF_ID].q_output_len);
status_upd1(i++, "BLEif_dg_in_qlen", eth_netif_array[BLE_NETIF_ID].input_queue_len);
status_upd1(i++, "BLEif_cbk_p", eth_netif_array[BLE_NETIF_ID].callback_pending);
status_upd(i++, "", "");
status_upd1(i++, "LWif_dg_in", eth_netif_array[LWIP_NETIF_ID].dgrams_in);
status_upd1(i++, "LWif_dg_lost", eth_netif_array[LWIP_NETIF_ID].dgrams_lost);
status_upd1(i++, "LWif_dg_out", eth_netif_array[LWIP_NETIF_ID].dgrams_out);
status_upd1(i++, "LWif_dg_outqlen", eth_netif_array[LWIP_NETIF_ID].q_output_len);
status_upd1(i++, "LWif_dg_in_qlen", eth_netif_array[LWIP_NETIF_ID].input_queue_len);
status_upd1(i++, "LWif_cbk_p", eth_netif_array[LWIP_NETIF_ID].callback_pending);
status_upd(i++, "", "");
status_upd1(i++, "NAT_pbuf_brk", nat_stat.pbuf_broken);
status_upd1(i++, "NAT_tcp_new", nat_stat.tcp_new);
status_upd1(i++, "NAT_tcp_close", nat_stat.tcp_close);
status_upd(i++, "", "");
status_upd1(i++, "eth_pbuf used", xeth_pbuf_ctrl.used);
status_upd1(i++, "eth_queue used", xeth_queuepool_ctrl.used);
status_upd1(i++, "nat pbuf used", nat_stat.pbuf_used);
status_upd1(i++, "nat lw conn used", nat_stat.lw_conn_used);
}
if (dbg_scr_num==2) {
status_upd1(i++, "tx_raw", ble_tcp_stats.tx_raw);
status_upd1(i++, "rx_raw", ble_tcp_stats.rx_raw);
status_upd1(i++, "tx_blocks", ble_tcp_stats.tx_blocks);
status_upd1(i++, "rx_blocks", ble_tcp_stats.rx_blocks);
status_upd1(i++, "tx_err", ble_tcp_stats.tx_err);
status_upd1(i++, "tx_ack_err", ble_tcp_stats.tx_ack_err);
status_upd1(i++, "tx_sack_err", ble_tcp_stats.tx_sack_err);
// status_upd1(i++, "tx_ack_negd_err", ble_tcp_stats.tx_ack_negdist_err);
// status_upd1(i++, "tx_ack_toom_err", ble_tcp_stats.tx_ack_toomuch_err);
// status_upd1(i++, "ack_upd", ble_tcp_stats.ack_upd);
// status_upd1(i++, "rx_empty_dg", ble_tcp_stats.rx_empty_dg);
// status_upd1(i++, "rx_only_ack", ble_tcp_stats.rx_only_ack);
status_upd1(i++, "rx_seq_err", ble_tcp_stats.rx_seq_err);
// status_upd1(i++, "rx_dup_ack", ble_tcp_stats.rx_dup_ack);
// status_upd1(i++, "rx_neg_ack", ble_tcp_stats.rx_neg_ack);
status_upd1(i++, "rx_duplicates", ble_tcp_stats.rx_duplicates);
status_upd1(i++, "rx_rtr_jmps", ble_tcp_stats.rx_detected_retransmit_jumps);
// status_upd1(i++, "rx_pl1", ble_tcp_stats.rx_detected_packet_loss_single);
// status_upd1(i++, "rx_pl2+", ble_tcp_stats.rx_detected_packet_loss_multiple);
status_upd1(i++, "rx_incor_jmps", ble_tcp_stats.rx_detected_incorrect_jumps);
char b[100]; int ptr=0;
// for (int i=0; i<8; i++) ptr+=sprintf(b+ptr, "%d ",tx_busy_mask[i]);
status_upd(i++, "tx_busy_mask", b);
// status_upd1(i++, "tx_ack_blk", tx_ack_blk);
status_upd1(i++, "tx_index_blk", tx_index_blk);
status_upd1(i++, "tx_push_ptr_blk", tx_push_ptr_blk);
ptr=0;
// for (int i=0; i<8; i++) ptr+=sprintf(b+ptr, "%d ",rx_ready_mask[i]);
status_upd(i++, "rx_ready_mask", b);
status_upd1(i++, "rx_nack_blk", rx_nack_blk);
// status_upd1(i++, "rx_last_rcvd_blk", rx_last_recvd_blk);
status_upd1(i++, "conn_rst", ble_tcp_stats.rst_cnt);
status_upd1(i++, "conn_rst_req", ble_tcp_stats.rstreq_cnt);
status_upd1(i++, "ble_tx_busy", ble_tcp.ble_tx_busy);
status_upd1(i++, "rxasm_try", ble_tcp_stats.rxasm_try);
status_upd1(i++, "rxasm_throttle", ble_tcp_stats.rxasm_throttle);
}
while (i<=30) status_upd(i++, "", "");
usleep(100000);
}
}
JNIEXPORT void JNICALL
Java_ua_cn_stu_navigation_MainActivity_change_1dbg_1scr(JNIEnv *env, jobject thiz, jint scr) {
dbg_scr_num=scr;
}
pthread_t frameThreadHandle;
extern uint8_t imageCubes[];
extern uint8_t imageWolf[];
JNIEnv* frame_env;
void frameThread(void *argsw)
{
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6; // choose your JNI version
args.name = NULL;
args.group = NULL;
jint ret=(*gJvm)->AttachCurrentThread(gJvm, &frame_env, &args);
if (ret) return;
static unsigned char parity;
while(1)
{
usleep(50000);
if (frame_method)
{
JNIEnv *env = frame_env;
jbyteArray dgramm = (*env)->NewByteArray(env, 132 * 8);
if (dgramm == NULL) continue;
(*env)->SetByteArrayRegion (env, dgramm, 0, 132 * 8, ! parity ? imageWolf : imageCubes);
(*env)->CallStaticVoidMethod(env, bleserv, frame_method, dgramm);
(*env)->DeleteLocalRef(env, dgramm);
parity = !parity;
}
}
}
void frameThreadInit()
{
TaskCreate (frameThread, &frameThreadHandle);
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* pjvm, void* reserved) {
gJvm = pjvm;
JNIEnv* env;
if ((*pjvm)->GetEnv(pjvm, &env, JNI_VERSION_1_6) != JNI_OK) {return JNI_ERR;}
bleserv = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "ua/cn/stu/navigation/MainActivity"));
if (bleserv == NULL) return JNI_ERR;
bleserv1 = (*env)->NewGlobalRef(env, (*env)->FindClass(env, "ua/cn/stu/navigation/MainActivity"));
if (bleserv1 == NULL) return JNI_ERR;
send_method = (*env)->GetStaticMethodID(env, bleserv, "send_to_ble","([B)I");
if (send_method == NULL) return JNI_ERR;
frame_method = (*env)->GetStaticMethodID(env, bleserv, "frame", "([B)V");
if (frame_method == NULL) return JNI_ERR;
status_upd_method = (*env)->GetStaticMethodID(env, bleserv, "upd_status_param","(I[B[B)V");
if (status_upd_method == NULL) return JNI_ERR;
TaskCreate(status_thread, &thr);
eth_router_init();
eth_ble_if_init();
ble_tcp_init();
MX_LWIP_Init();
topology_init();
frameThreadInit();
return JNI_VERSION_1_6;
}
//JNIEXPORT void JNICALL Java_ua_cn_stu_navigation_MainActivity_char_1wr_1cbk(JNIEnv *env, jobject thiz, jint status) {
// ble_tx_complete(status);
//}
JNIEXPORT void JNICALL
Java_ua_cn_stu_navigation_ble_BluetoothLeService_char_1wr_1cbk(JNIEnv *env, jclass clazz,
jint status) {
ble_tx_complete(status);
}
JNIEXPORT void JNICALL
Java_ua_cn_stu_navigation_MainActivity_new_1dg_1from_1bt(JNIEnv *env, jobject thiz, jbyteArray jdgram) {
dbg[4]++;
jbyte *stateJava = (*env)->GetByteArrayElements(env, jdgram, NULL);
if (stateJava == NULL) return ;
jint len = (*env)->GetArrayLength(env, jdgram);
if (len>0) process_gatt_data(stateJava, len);
// int pid=getpid();
// int ppid=getppid();
// int tid = gettid();
// print_log("tid %d pid %d ppid %d recvd %d bytes",tid, pid, ppid, len);
(*env)->ReleaseByteArrayElements(env, jdgram, stateJava, 0);
}
JNIEXPORT void JNICALL
Java_ua_cn_stu_navigation_MainActivity_eth_1ble_1stack_1control(JNIEnv *env, jobject thiz,
jint status) {
// status:
// 0 - service started
// 1 - service shutdown request
// 2 - ble connection up
// 3 - ble connection down
ble_connection_status=status;
if (status==2) gatt_conn_reset();
}
JNIEXPORT void JNICALL
Java_ua_cn_stu_navigation_MainActivity_tap_1detected(JNIEnv *env, jobject thiz, jint area) {
// tap_detected(area);
dbg[2]++;
}
JNIEXPORT void JNICALL
Java_ua_cn_stu_navigation_MainActivity_coord_1from_1terminal(JNIEnv *env, jobject thiz, jint x_pix,
jint y_pix) {
static volatile char x;
x++;
// TODO: implement coord_from_terminal()
}
JNIEXPORT void JNICALL
Java_ua_cn_stu_navigation_MainActivity_button_1from_1terminal(JNIEnv *env, jobject thiz,
jint button_id) {
volatile int lol = button_id;
// TODO: implement button_from_terminal()
}
//JNIEXPORT void JNICALL Java_ua_cn_stu_navigation_MainActivity_eth_1ble_1stack_1control(JNIEnv *env, jobject thiz, jint status) {
//// status:
//// 0 - service started
//// 1 - service shutdown request
//// 2 - ble connection up
//// 3 - ble connection down
// ble_connection_status=status;
// if (status==2) gatt_conn_reset();
//}
+9
View File
@@ -0,0 +1,9 @@
#ifndef TESTBLE_BT_DRV_H
#define TESTBLE_BT_DRV_H
#include <jni.h>
int bt_send(uint8_t* dgr, uint16_t dglen);
void send_thread_register();
extern volatile int ble_connection_status;
#endif //TESTBLE_BT_DRV_H
+377
View File
@@ -0,0 +1,377 @@
// ETH_MEM ver 1.0
#include "xlib.h"
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "eth_mem.h"
#include "eth_router.h"
sem_t eth_mem_sem;
// ============ task for queue management
struct ETH_MEM_STATS eth_mem_stats;
// private function prototypes
static void EthQueueTask(void *argument);
static void eth_custom_pbuf_free_request(struct pbuf* p);
#define taskNOTIFY_NEW_FREE_P_REQUEST 1// освобождение элемента очереди
#define taskNOTIFY_NEW_P_REQUEST 4// дефицит pbuf
#define taskNOTIFY_ROUTER_Q_UPDATE 16// толкнуть обработчик очередей (роутер)
// ref увеличивается только в главном пакете из цепочки.
inline static struct ETH_PBUF* do_eth_pbuf_alloc(struct ETH_PBUF_CTRL* eth_pbuf_ctrl, struct NOMEM_CALLBACK* cb) {
struct ETH_PBUF* p=(struct ETH_PBUF*)eth_pbuf_ctrl->free_chain;
if (p==NULL) {// no memory
if (cb) {
if (cb->wait_active) return NULL;
eth_mem_stats.eth_pbuf_alloc_delayed++;
if (eth_mem_stats.eth_pbuf_alloc_delayed==2) {}
cb->next_p=NULL;
struct NOMEM_CALLBACK* nopbuf_queue_prev=(struct NOMEM_CALLBACK*)eth_pbuf_ctrl->pool->nopbuf_q_end;
if (nopbuf_queue_prev) nopbuf_queue_prev->next_p=cb; else eth_pbuf_ctrl->pool->nopbuf_q_begin=cb;
eth_pbuf_ctrl->pool->nopbuf_q_end=cb;
cb->wait_active=1;
}
else eth_mem_stats.eth_pbuf_alloc_fails++;
return NULL;
}
eth_pbuf_ctrl->free_chain=(struct ETH_PBUF*)p->pbuf.next;
eth_pbuf_ctrl->used++;
if (eth_pbuf_ctrl->used>eth_pbuf_ctrl->used_max) eth_pbuf_ctrl->used_max=eth_pbuf_ctrl->used;
p->pbuf.next=NULL;
int pbuf_num=(p-&eth_pbuf[0]);
return p;
}
struct ETH_PBUF* eth_pbuf_alloc(struct ETH_PBUF_CTRL* eth_pbuf_ctrl, struct NOMEM_CALLBACK* cb) {
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
struct ETH_PBUF* p=do_eth_pbuf_alloc(eth_pbuf_ctrl, cb);
ETH_MEM_UNPROTECT();
if (cb) {
if (p==NULL) {
TNotifyAdd(&eth_pbuf_ctrl->pool->tNotifyHandle, taskNOTIFY_NEW_P_REQUEST);
return NULL;
}
p->pbuf.if_idx = cb->src_interface_id;
}
else p->pbuf.if_idx=0;
p->pbuf.ref=1;
p->pbuf.type_internal=0;// payload directly follows the struct pbuf
p->pbuf.flags=PBUF_FLAG_IS_CUSTOM;// bufer have custom free function
p->pbuf.payload=p->default_payload;
return p;
}
static struct ETH_QUEUEPOOL_CTRL* xpool;
// добавить мост. выделяем пул для пакетных буферов моста, память для интерфейсов
void eth_router_add_bridge(struct ETH_QUEUEPOOL_CTRL* pool, struct ETH_QUEUE* eth_q, uint32_t pool_mem_size_blocks,
struct ETH_PBUF_CTRL* eth_pbuf_ctrl, struct ETH_PBUF* eth_pbuf, uint8_t* eth_pbuf_mem, uint32_t eth_pbufs_cnt,
struct ETH_NETIF* netif_arr, uint32_t netif_count) {
// pbufs init
eth_pbuf_ctrl->free_chain=eth_pbuf;
eth_pbuf_ctrl->pool=pool;
for (int i=0; i<eth_pbufs_cnt; i++) {// initialize all PBUFs
eth_pbuf[i].default_payload=&eth_pbuf_mem[i*ETH_MEM_BUF_SIZE];// link PBUF with memory chunk (in separate space)
eth_pbuf[i].pbuf.type_internal=0;// payload directly follows the struct pbuf
eth_pbuf[i].pbuf.flags=PBUF_FLAG_IS_CUSTOM;// bufer have custom free function
eth_pbuf[i].pbuf.ref=0;// reference count (1 - first allocate)
eth_pbuf[i].pbuf.if_idx=0;// network interface index (0 = no index)
eth_pbuf[i].src_if=0;// network interface index (0 = no index)
eth_pbuf[i].custom_free_function=&eth_custom_pbuf_free_request;// pointer to custom free function
eth_pbuf[i].ctrl=eth_pbuf_ctrl;// link for fast navigate to PBUF control structure
}
for (int i=0; i<eth_pbufs_cnt-1; i++) {// chain all PBUFs (allocation in future get PBUF from this chain)
eth_pbuf[i].pbuf.next=(struct pbuf*)&eth_pbuf[i+1];
}
eth_pbuf[eth_pbufs_cnt-1].pbuf.next=NULL;
// pool init
for (int i=0; i<pool_mem_size_blocks-1; i++) eth_q[i].next=&eth_q[i+1];// chain all free queue control structs for future allocation
eth_q[pool_mem_size_blocks-1].next=NULL;// нужно только в случае переинициализации пула
pool->used=0;// выделено блоков (статистика)
pool->used_max=0;// пик выделения (статистика)
pool->q_begin=eth_q;
pool->eth_netif_array=netif_arr;
pool->eth_netif_size=netif_count;
for (int i=0; i<netif_count; i++) {
netif_arr[i].q_output_end=NULL;
netif_arr[i].q_output_begin=NULL;
netif_arr[i].q_output_len=0;
netif_arr[i].q_output_len_max=0;
netif_arr[i].q_output_size=1;
netif_arr[i].callback_fn=NULL;
netif_arr[i].q_update_cbk=NULL;
netif_arr[i].pool=pool;
netif_arr[i].eth_netif_id=i;
netif_arr[i].if_up=0;
netif_arr[i].callback_pending=0;
}
for (int i=0; i<pool_mem_size_blocks; i++) {// проинициализируем заранее поля буферов один раз, чтобы не обновлять при каждой аллокации
eth_q[i].state=st_free;
eth_q[i].pool=pool;
}
xpool=pool;
}
void eth_router_start_task(struct ETH_QUEUEPOOL_CTRL* pool) {
sem_init(&eth_mem_sem, 0, 1);
TNotifyCreate(&pool->tNotifyHandle);
TaskCreate (EthQueueTask, &pool->pThr);
}
static void eth_custom_pbuf_free_request(struct pbuf* p) {// callback from LWIP pbuf
p->ref=1;// lwip уже декрементировал ref. Чтобы нам корректно освободить, нужно ref вернуть.
eth_pbuf_free_request((struct ETH_PBUF*)p);
}
void eth_pbuf_free_request(struct ETH_PBUF* xpbuf) {// добавлене в очередь на освобождение блока (или передачу другому владельцу)
struct ETH_QUEUEPOOL_CTRL* pool=xpbuf->ctrl->pool;
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
if (xpbuf->pbuf.ref>1) {
xpbuf->pbuf.ref--;
ETH_MEM_UNPROTECT();
return;
}
if (xpbuf->pbuf.ref==0) EM_ASSERT(1);// already free?
int pbuf_num=(xpbuf-&eth_pbuf[0]);
xpbuf->pbuf.next=NULL;//this pbuf must be last in chain
if (pool->free_pbuf_q_end) {// pbuf is not empty
if (pool->free_pbuf_q_end->pbuf.next) EM_ASSERT(2);// ASSERT: invalid pointer to last pbuf. last pbuf not marked as last in chain
pool->free_pbuf_q_end->pbuf.next=&xpbuf->pbuf;// add to end of chain
} else pool->free_pbuf_q_begin=xpbuf;
pool->free_pbuf_q_end=xpbuf;
ETH_MEM_UNPROTECT();
TNotifyAdd(&pool->tNotifyHandle, taskNOTIFY_NEW_FREE_P_REQUEST);
}
static void free_blk(struct ETH_QUEUEPOOL_CTRL* pool) {// освободим блоки из очереди на освобождение
while (1) {
// взятие освобождаемого ETH_PBUF из очереди
struct ETH_PBUF* xpbuf=(struct ETH_PBUF*)pool->free_pbuf_q_begin;// pbuf в начале очереди
if (xpbuf==NULL) { /*ETH_MEM_UNPROTECT();*/ break; }
if (xpbuf->pbuf.ref!=1) EM_ASSERT(3);// ASSERT: invalid allocation counter
int src_if=xpbuf->src_if;
xpbuf->src_if=0;
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
pool->eth_netif_array[src_if].input_queue_len--;
struct ETH_PBUF* n=(struct ETH_PBUF*)xpbuf->pbuf.next;// кто следующий в очереди
pool->free_pbuf_q_begin=n;// продвигаем очередь
if (n==NULL) pool->free_pbuf_q_end=NULL;// если очередь пуста
// действие с освобождаемым ETH_PBUF (освобождение или передача)
if (pool->nopbuf_q_begin) {// pass memory to new owner directly
struct NOMEM_CALLBACK* cb=(struct NOMEM_CALLBACK*)pool->nopbuf_q_begin;
pool->nopbuf_q_begin=cb->next_p;
if (pool->nopbuf_q_begin==NULL) pool->nopbuf_q_end=NULL;
cb->wait_active=0;
ETH_MEM_UNPROTECT();
cb->next_p=NULL;// на всякий случай, в принципе это не нужно
eth_mem_stats.eth_pbuf_alloc_delay_cbks++;
xpbuf->pbuf.if_idx = cb->src_interface_id;
cb->callback_fn(xpbuf, cb);// нужно выделить только pbuf
}
else {// free memory
xpbuf->pbuf.next=(struct pbuf*)xpbuf->ctrl->free_chain;// освобождаемый блок добавляем в начало очереди
xpbuf->ctrl->free_chain=xpbuf;
xpbuf->pbuf.ref=0;// для порядка. в продакшене не требуется
if (xpbuf->ctrl->used==0) EM_ASSERT(4);
xpbuf->ctrl->used--;
ETH_MEM_UNPROTECT();
}
if (pool->eth_netif_array[src_if].q_update_cbk) pool->eth_netif_array[src_if].q_update_cbk(&pool->eth_netif_array[src_if]);// вызовем callback, что очередь стала меньше
}
}
// Процесс, обслуживающий:
// - очередь запросов на освобождение памяти
// - очередь коллбэков на выделение памяти (тем кто в очереди на получение памяти при дефиците памяти)
// - очередь пакетов на роутинг
static void EthQueueTask(void* arg) {
struct ETH_QUEUEPOOL_CTRL* pool=xpool;
while (1) {
uint32_t res=TNotifyWait(&pool->tNotifyHandle);
if (res & taskNOTIFY_NEW_FREE_P_REQUEST) {// new pbuf_free requests
free_blk(pool);
}
if (res & taskNOTIFY_ROUTER_Q_UPDATE) {// new dgram in queue
while (1) {
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
struct ETH_QUEUE* queue=(struct ETH_QUEUE*)pool->q_input_begin;
if (queue==NULL) { ETH_MEM_UNPROTECT(); break; }
struct ETH_QUEUE* n=queue->next;
pool->q_input_begin=n;// забираем из очереди
if (n==NULL) pool->q_input_end=NULL;
queue->next=NULL;
pool->q_input_used--;
ETH_MEM_UNPROTECT();
eth_route_block(queue);// и отдаём в роутинг
if (pool->free_pbuf_q_begin) free_blk(pool);
}
}
}
}
// Выделить блок памяти.
inline static struct ETH_QUEUE* do_eth_queue_entry_alloc(struct ETH_QUEUEPOOL_CTRL* pool) {
struct ETH_QUEUE* queue = (struct ETH_QUEUE*)pool->q_begin;// try to allocate queue
if (queue==NULL) {
pool->alloc_fails++;
eth_mem_stats.qpool_alloc_fails++;
return NULL;
}
pool->q_begin = queue->next;// update pointer to next free queue
pool->used++;
if (pool->used_max < pool->used) pool->used_max = pool->used;
queue->state = st_allocated;
return queue;// allocated memory
}
static struct ETH_QUEUE* eth_queue_entry_alloc(struct ETH_QUEUEPOOL_CTRL* pool) {
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
struct ETH_QUEUE* q=do_eth_queue_entry_alloc(pool);
ETH_MEM_UNPROTECT();
return q;
}
void eth_queue_entry_free(struct ETH_QUEUE* queue) {// освобождение элемента очереди
struct ETH_QUEUEPOOL_CTRL* pool=queue->pool;
if (queue->state==st_free) EM_ASSERT(5);// ASSERT: trying to free not used queue
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
queue->state=st_free;
queue->next=(struct ETH_QUEUE*)pool->q_begin;// освобождаемый блок добавляем в начало очереди
pool->q_begin=queue;
pool->used--;
ETH_MEM_UNPROTECT();
}
#pragma optimize=none
void eth_add_packet_to_router_queue(struct ETH_PBUF* xpbuf) {
uint32_t nif=xpbuf->pbuf.if_idx;
if (xpbuf->pbuf.ref==0) EM_ASSERT(11);
if (nif>=ETH_NETIFS) EM_ASSERT(6);//
xpbuf->src_if=nif;
if (xpbuf->pbuf.len<14) {// invalid datagram. 14 bytes (src mac+dst mac + ethertype) required
eth_pbuf_free_request(xpbuf);
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
xpbuf->ctrl->pool->eth_netif_array[nif].dgrams_lost++;
ETH_MEM_UNPROTECT();
return;
}
struct ETH_QUEUEPOOL_CTRL* pool=xpbuf->ctrl->pool;
struct ETH_QUEUE* queue=eth_queue_entry_alloc(pool);
if (queue==NULL) {
eth_pbuf_free_request(xpbuf);
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
pool->eth_netif_array[nif].dgrams_lost++;
ETH_MEM_UNPROTECT();
return;
}
queue->next = NULL;
queue->state = st_in_queue;
queue->pbuf = xpbuf;
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
pool->eth_netif_array[nif].input_queue_len++;
pool->eth_netif_array[nif].dgrams_in++;
if (pool->q_input_end!=NULL) pool->q_input_end->next=queue; else pool->q_input_begin=queue;
pool->q_input_end=queue;
pool->q_input_used++;
if (pool->q_input_used_max<pool->q_input_used) pool->q_input_used_max=pool->q_input_used;
ETH_MEM_UNPROTECT();
TNotifyAdd(&pool->tNotifyHandle, taskNOTIFY_ROUTER_Q_UPDATE);
}
struct ETH_PBUF* eth_get_packet(struct ETH_NETIF* enetif) {// запрос пакета из исходящей очереди драйвером для передачи во внешний мир
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
struct ETH_QUEUE* queue=(struct ETH_QUEUE*)enetif->q_output_begin;
if (queue) {// packet ready
struct ETH_QUEUE* next_queue=queue->next;
enetif->q_output_begin=next_queue;
if (next_queue == NULL) enetif->q_output_end = NULL;
if (enetif->q_output_len==0) EM_ASSERT(7);// ASSERT: сбой подсчета размера очереди.
enetif->q_output_len--;
enetif->dgrams_out++;
ETH_MEM_UNPROTECT();
queue->next=NULL;
queue->state=st_sending;
struct ETH_PBUF* xpbuf=queue->pbuf;
eth_queue_entry_free(queue);
return xpbuf;
}
if (enetif->callback_fn) enetif->callback_pending=1;
ETH_MEM_UNPROTECT();
return NULL;
}
void eth_add_packet_to_output_queue(struct ETH_QUEUE* queue, struct ETH_NETIF* enetif) {// для роутера. отправить в исходящую очередь нужного интерфейса (или передать сразу драйверу, если он ждёт пакет)
queue->next = NULL;
if (queue->pbuf->pbuf.ref==0) EM_ASSERT(8);
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
if (enetif->callback_pending) {// интерфейс ожидает блок - отправляем сразу в интерфейс без очереди
if (enetif->q_output_end) EM_ASSERT(9);// assert: драйвер ждёт пакет, но в очереди почему-то что-то есть. Хотя должно быть пусто...
enetif->callback_pending=0;
queue->state = st_sending;
enetif->dgrams_out++;
ETH_MEM_UNPROTECT();
struct ETH_PBUF* xpbuf=queue->pbuf;
eth_queue_entry_free(queue);
if (enetif->callback_fn) enetif->callback_fn(xpbuf, enetif);
else EM_ASSERT(10);// no callback
return;
}
if (enetif->q_output_len>=enetif->q_output_len_max) {// очередь уже полна. дропаем пакет.
enetif->dgrams_lost++;
ETH_MEM_UNPROTECT();
eth_pbuf_free_request(queue->pbuf);
eth_queue_entry_free(queue);
return;
}
queue->state = st_in_queue;// добавляем в очередь
if (enetif->q_output_end) enetif->q_output_end->next=queue; else enetif->q_output_begin=queue;// этот элемент приписываем к концу очереди
enetif->q_output_end=queue;// конечным элементом ставим этот элемент
enetif->q_output_len++;
if (enetif->q_output_len_max<enetif->q_output_len) enetif->q_output_len_max=enetif->q_output_len;
ETH_MEM_UNPROTECT();
}
struct ETH_QUEUE* eth_mem_clone(struct ETH_QUEUE* queue) {
struct ETH_QUEUE* queue_copy=eth_queue_entry_alloc(queue->pool);
if (queue_copy) {
queue_copy->pbuf=queue->pbuf;
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
queue->pbuf->pbuf.ref++;
ETH_MEM_UNPROTECT();
}
return queue_copy;
}
+234
View File
@@ -0,0 +1,234 @@
#pragma once
#include <semaphore.h>
#include "xlib.h"
#include "eth_router_cfg.h"
#include "lwip/pbuf.h"
/* Менеджер памяти и очередей для ethernet пакетов.
Умеет:
- выделять и освобождать память из пулов (пока пул один, но архитектурно заложена возможность использования нескольких пулов)
- при ошибке выделения памяти вызвать callback как только память появилась (т.е. как только кто-то освободил)
- работать с очередями: помещать пакеты из всех интерфейсов в общую очередь на роутинг (из irq или потока)
Менеджер содержит в себе поток, обслуживающий нужды очереди менеджера памяти и очередь на роутинг. Из этого потока вызываются все коллбэки.
Коллбэки могут заниматься среднезатратными по времени вещами (например, копирование всего пакета или подсчет CRC всего пакета), но не могут вставать в ожидание чего-либо.
Ожидание коллбэков будет тормозить обработку входящих очередей с интерфейсов и очереди на операции с памятью.
Роутер из очереди на роутинг распихивает пакеты в интерфейсы назначения. Если при попытке запихнуть пакет в интерфейс назначения размер очередь этого интерфейса заполнена, пакет отбрасывается.
Для броадкастов роутером создаются копии пакета на каждый исходящий интерфейс. Ибо нужно каждую копию запихнуть в свою очередь, а очередь у пакета только одна.
Рекомендуемый размер входящих очередей - 2 пакета: один в процессе приёма, второй в потоке роутера.
Пакеты во входящих очередях обрабатываются сразу (как это позволть сделать приоритет потока обработчика).
Размер исходящих очередей должен быть больше, его задача удерживать в буферах всё что вовремя не пролезает через медленные интерфейсы.
Пока пакет не фрагментируется. Всё что не влезает в размер одного буфера (ETH_MEM_BUF_SIZE), отбрасывается.
Рекомендации по драйверам интерфейсов:
- при инициализации:
eth_netif_array[YOUR_NETIF_ID].q_output_len_max=<размер очереди на передачу в пакетах>
eth_netif_array[YOUR_NETIF_ID].callback_fn=lwip_callback_from_bridge;// инициализируем callback (пакет готов)
eth_netif_array[ETH_NETIF_ID].if_up=1;// интерфейс готов принимать пакеты
- выделить память из пула перед приёмом пакета (т.е. буфера резервируются когда инициализируются буфера приёма), и записывать пакет сразу в эту память.
- если при инициализации буфера был отказ в выделении памяти, ждать коллбэк. Когда прилетит callback, можно инициализировать буфер и запускать приём.
Передача:
1. инициализируем callback на новый пакет.
2. запрашиваем пакет (eth_get_packet). Функция либо возвратит что есть в очереди, либо активирует коллбэк. В этом случае ждем пакет.
3. когда пакет получен, передаем пакет
4. повторяем начиная с пп.2
Обработчик коллбэка вызывается один раз после того как eth_get_packet вернул NULL (т.е. отсутствие пакета)
*/
// параметры инициализации пула по умолчанию:
extern sem_t eth_mem_sem;
#define ETH_MEM_ALIGN __attribute__((aligned(4)))// для CPU без кеша
#define ETH_MEM_DECL_PROTECT()
#define ETH_MEM_PROTECT() {sem_wait(&eth_mem_sem); /*asm("DSB SY");*/}
#define ETH_MEM_UNPROTECT() {/*asm("DSB SY");*/ sem_post(&eth_mem_sem);}
#define EM_ASSERT(x) {dbg[10]=x; while(1);}
// ======================== Управляющие структуры =============
struct ETH_PBUF_CTRL {
volatile struct ETH_PBUF* free_chain;// linked-list для размещения-освобождения буферов
volatile uint32_t used;// счетчик, сколько сейчас элементов занято
uint32_t used_max;// сколько было занято максимум
struct ETH_QUEUEPOOL_CTRL* pool;
};
#ifndef PBUF_FLAG_IS_CUSTOM// cleck for LWIP pbuf is included
#define PBUF_FLAG_IS_CUSTOM 0x02U
struct pbuf {
struct pbuf *next; // next fragment in chain (NULL - end of packet)
void *payload; // memory for packet payload
uint16_t tot_len; // remain packet length from begin of this part
uint16_t len; // this fragment length
uint8_t type_internal; // payload directly follows the struct pbuf
uint8_t flags; // PBUF_FLAG_IS_CUSTOM
uint8_t ref; // reference count
uint8_t if_idx; // network interface index
};
typedef void (*pbuf_free_custom_fn)(struct pbuf *p);
#endif
struct ETH_PBUF {
struct pbuf pbuf;
// struct pbuf: *next // next fragment in chain (NULL - end of packet)
// void *payload; // memory for packet payload
// u16_t tot_len; // remain packet length from begin of this part
// u16_t len; // this fragment length
// u8_t type_internal; // payload directly follows the struct pbuf
// u8_t flags; // PBUF_FLAG_IS_CUSTOM
// LWIP_PBUF_REF_T ref; // reference count
// u8_t if_idx; // network interface index
// pbuf_free_custom_fn // custom pbuf free function
pbuf_free_custom_fn custom_free_function;
uint8_t* default_payload;
uint8_t src_if;
struct ETH_PBUF_CTRL* ctrl;
};
struct ETH_QUEUE {// ячейка пула
struct ETH_QUEUE* next;// указатель на следующий элемент списка (очереди, которая определяется параметром mia_state)
struct ETH_QUEUEPOOL_CTRL* pool;
struct ETH_PBUF* pbuf;// Обращаться к ETH_PBUF / pbuf нужно через этот указатель!
volatile enum {
st_free=0,// ячейка свободна, поле next указывает на следующую свободную ячейку, т.е. используется дл выделения памяти
st_allocated=1,// ячейка занята, идёт процесс записи данных в ячейку, поле next не используется
st_in_queue=2,// ячейка в очереди на обработку, поле next указывает на следующую ячейку в данной очереди
st_sending=3,// в процессе отправки на интерфейсе назначения
st_free_pending=4 } state;// ячейка в очереди на освобождение (или передачи другому ожидающему память владельцу), поле next указывает на следующий элемент очереди на совобождение
uint8_t dst_if_idx;// если 0 - то роутится роутером. Если не 0, то роутится в соответствующиё исходящий интерфейс
};
struct ETH_MEM_STATS {
uint32_t qpool_alloc_fails;// queue entry alloc fail (summary, for all queues)
uint32_t eth_pbuf_alloc_fails;
uint32_t eth_pbuf_alloc_delayed;
uint32_t eth_pbuf_alloc_delay_cbks;
};
extern struct ETH_MEM_STATS eth_mem_stats;
struct NOMEM_CALLBACK {// структура для организации очереди коллбэков на выделение памяти для входящих пакетов, т.е. принимаемых драйвером (экземпляры структуры создаются интерфейсом)
void (*callback_fn)(struct ETH_PBUF*, struct NOMEM_CALLBACK*);
struct NOMEM_CALLBACK* next_p;// chain for pbuf allocation requests
struct ETH_PBUF* p;
uint8_t src_interface_id;
uint8_t wait_active;// Если в состоянии ожидания выдачи памяти - то =1
};
struct ETH_NETIF {// сетевой интерфейс (элемент netif_list). определа в виде массива элементов заранее определенного размера, индекс является номером интерфейса и eth_netif_id.
volatile struct ETH_QUEUE* q_output_end;// сюда добавляем пакет после роутинга
volatile struct ETH_QUEUE* q_output_begin;// забираем пакет драйвером интерфейса
volatile uint32_t q_output_len; // размер исходящей очереди
volatile uint32_t q_output_len_max; // фиксируем пик очереди
volatile uint32_t q_output_size; // максимальный размер исходящей очереди. Количество элементов в пуле должно хватать для обслуживания всех очередей.
// входящая очередь не лимитируется (предполагается, что пакет во входящей очереди не задерждится надолго и быстро улетит в исходящую, либо отбросится если исходящая очередь пепеполнена).
void (*callback_fn)(struct ETH_PBUF*, struct ETH_NETIF*);// callback готовности пакета на передачу драйверу
struct ETH_QUEUEPOOL_CTRL* pool;// пул памяти, использующийся этим интерфейсом
void (*q_update_cbk)(struct ETH_NETIF*);// callback уменьшения кол-ва пакетов в ожидании обработки от этого интерфейса
uint8_t eth_netif_id;// ID интерфейса. всегда является индексом eth_netif_array. сделан для ускорения определения индекса по указателю.
volatile uint8_t if_up;// интерфейс включен (если 0, то интерфейс не используется для передачи-приема пакетов)
volatile uint8_t callback_pending;// ждём callback
uint32_t dgrams_in;
uint32_t dgrams_out;
uint32_t dgrams_lost;
uint32_t input_queue_len;// размер очереди кодограмм от этого интерфейса
char* if_name;
};
struct ETH_QUEUEPOOL_CTRL {// описание пула элементов для интерфейса моста
volatile struct ETH_QUEUE* q_begin;// начало списка свободных буферов. Сюда и добавляем освобождаемую память, и забираем при размещении (т.е. работает как стек)
volatile struct NOMEM_CALLBACK* nopbuf_q_end;// сюда добавляем / очередь желающих получить pbuf
volatile struct NOMEM_CALLBACK* nopbuf_q_begin;// отсюда забираем
volatile struct ETH_PBUF* free_pbuf_q_end;// добавляем - очередь запросов на освобождение блока
volatile struct ETH_PBUF* free_pbuf_q_begin;// забираем
volatile struct ETH_QUEUE* q_input_end;// добавляем - очередь входящих пакетов на роутинг
volatile struct ETH_QUEUE* q_input_begin;// забираем
volatile uint32_t q_input_used;// счетчик, сколько сейчас элементов входящей очереди занято
volatile uint32_t q_input_used_max;// пик
volatile uint32_t used;// счетчик, сколько сейчас элементов пула занято
uint32_t used_max;// сколько было занято максимум
volatile uint32_t alloc_fails;// счетчик ошибок выделения
struct ETH_NETIF* eth_netif_array;// массив структур описывающих подключенные сетевые интерфейсы
struct NHandle_t tNotifyHandle;// процесс, обслуживающий этот пул
pthread_t pThr;
uint8_t eth_netif_size;// количество элементов структуры eth_netif_array
};
// ======================== API =============
// проинициализировать мост:
// - кастомный пул памяти (pool - управляющая структура, pool_mem - структура блоков памяти для пула, pool_mem_size_blocks - количество блоков памяти)
// - пул очередей
// не thread-safe. пул можно переинициализировать в любой момент. Пока не завершена (пере)инициализация нельзя пользоваться функциями работы с пулом.
// т.е. сперва инициализируем пул, потом запускаем периферию интерфейсов.
void eth_router_add_bridge(struct ETH_QUEUEPOOL_CTRL* pool, struct ETH_QUEUE* eth_q, uint32_t pool_mem_size_blocks,
struct ETH_PBUF_CTRL* eth_pbuf_ctrl, struct ETH_PBUF* eth_pbuf, uint8_t* eth_pbuf_mem, uint32_t eth_pbufs_cnt,
struct ETH_NETIF* netif_arr, uint32_t netif_count);
void eth_router_start_task(struct ETH_QUEUEPOOL_CTRL* pool);
// Внутренняя функция
// выделить элемент очереди из пула pool (thread/irq safe, если настроено выше)
//struct ETH_QUEUE* eth_queue_entry_alloc(struct ETH_QUEUEPOOL_CTRL* pool);
// Функция для роутера
// Освобождаем блок (thread/irq safe, если настроено выше).
// Блок должен быть выделен из любого пула ETH_QUEUE.
void eth_queue_entry_free(struct ETH_QUEUE* q);
// Запрос пакета драйвером интерфейса из очереди (thread/irq safe, если настроено выше)
// Если пакет есть в очереди на передачу, пакет извлекается из очереди и указатель на него возвращается функцией.
// Драйвер должен передать пакет, затем освободить буфер.
// Если в очереди пусто, функция возвращает NULL и инициирует ожидание пакета в очереди. Как только в очереди появится новый пакет, будет вызван callback, описанный в структуре enetif.
// В вызове callback будет указатель на пакет и указатель на сетевой интерфейс.
// в enetif предварительно надо проинициализировать:
// callback_fn - указатель на callback-функцию;
struct ETH_PBUF* eth_get_packet(struct ETH_NETIF* enetif);
// Функция для драйвера сетевого интерфейса
// отправить принятый интерфейсом пакет в роутер (thread/irq safe, если настроено выше)
// перед этим вызовом предполагается что память была выделена функцией eth_pbuf_alloc, пакет записан в память pbuf->payload и в pbuf->if_idx вписан номер интерфейса.
// размер доступной памяти payload в байтах равен ETH_MEM_BUF_SIZE
void eth_add_packet_to_router_queue(struct ETH_PBUF* pbuf);
// Функция для роутера
// отправить пакет "block" в очередь исходящую очередь интерфейса "enetif" (только из потока роутера).
// либо если драйвер ждёт пакет, педедать его сразу, минуя очередь
void eth_add_packet_to_output_queue(struct ETH_QUEUE* queue, struct ETH_NETIF* enetif);
// Функция для роутера
// дублирует пакет и создает новую очередь для пакета.
// память пакета для всех копий общая. Поэтому изменеять содержимое пакета после клонирования нельзя.
// используется для броадкастов (отправка копии пакета на все интерфйесы)
struct ETH_QUEUE* eth_mem_clone(struct ETH_QUEUE* block);
// выделяет pbuf. Если указан CB, то при ошибке выделения как только появится свободный ETH_PBUF, будет вызван callback с этим ETH_PBUF
// Для активации CB нужен заранее проинициализированный экземпляр структуры callback.
// Если предполагается очередь из нескольких callback-ов на отказ памяти, то для всех callback-ов, которые одновременно могут находиться в очереди, нужен отдельный экземпляр структуры.
// Рекомендуется при первом отказе памяти перестать размещать новые блоки и дождаться callback-а. В коллбэке можно пытаться дальше выделять память до первой ошибки.
// в cb предварительно надо проинициализировать:
// callback_fn - указатель на callback-функцию;
// src_interface_id - номер интерфейса (он проинициализируется в pbuf). Также можно использовать для определения экземпляра драйвера (если один обработчик на несколько интерфейсов)
// Нумерация интерфейсов - от единицы. 0 означает "не проинициализировано". Драйвер должен установить корректно номер интерфейса, иначе будут проблемы с роутингом.
// если cb=NULL, то номер интерфейса нужно будет проинициализировать самостоятельно после выделения блока.
struct ETH_PBUF* eth_pbuf_alloc(struct ETH_PBUF_CTRL* eth_pbuf_ctrl, struct NOMEM_CALLBACK* cb);
// Освобождаем блок (thread/irq safe, если настроено выше).
// Блок должен быть выделен из любого пула ETH_PBUF.
void eth_pbuf_free_request(struct ETH_PBUF* pbuf);
+489
View File
@@ -0,0 +1,489 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <strings.h>
#include <errno.h>
#include "lwip/opt.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "lwip/mem.h"
#include "dnsproxy.h"
#include "eth_router.h"
#include "eth_queue.h"
#include "lwip/lwip.h"
#include "eth_nat.h"
#include "linux/tcp.h"
#define PROT_TCP 6
#define PROT_UDP 17
#define PROT_ICMP 1
#define NAT_DIVERT_PORT 1234
pthread_t tnatHandle;
pthread_t tnatRXHandle;
//static struct NHandle_t tNotifyHandle;
#define taskNOTIFY_NEW_DATA 1
// src ip:port / dst ip:port -> src ip/port / dst <- divert ip:port
// В пакете подменяется dst ip:port, и в таблицу nat пишется соответствие src ip:port к dst ip:port
struct NAT_TAB nattab[NAT_TAB_SIZE];
struct NAT_STAT nat_stat;
static int nat_task_pipe[2];
static int nat_rx_task_pipe[2];
_Noreturn static void calc_stats(void * arg) {
while(1) {
int nofl_conn = 0;
for (int i = 0; i < NAT_TAB_SIZE; i++) {
int didx=nattab[i].index_end-nattab[i].index_begin;
if (didx<0) didx+=SNDQ_MAXLEN;
nofl_conn+=didx;
// if (nattab[i].index_begin != nattab[i].index_end) nofl_conn++;
}
nat_stat.lw_conn_used = nofl_conn;
usleep(10000);
}
}
int forward_nat(struct ETH_QUEUE* block) {// пакет в интернет - заворачивается на локальный ip/port по таблице соответствий
struct ETH_PKT_HDR* pkt=(struct ETH_PKT_HDR*)block->pbuf->pbuf.payload;
if (pkt->ethertype!=htons(0x800)) return -1;// no match
if (pkt->ip_dst==0xffffffff) return -1;//broadcast
if ((gnetif.ip_addr.addr & gnetif.netmask.addr) == (pkt->ip_dst & gnetif.netmask.addr) ) return -1;// local dgram
if (pkt->proto!=PROT_TCP && pkt->proto!=PROT_UDP/* && pkt->proto!=PROT_ICMP*/) return -1;
uint32_t curtime=xTaskGetTickCount();
uint8_t* ip=&pkt->ip_src;
uint16_t port=htons(pkt->port_src);
uint8_t* dip=&pkt->ip_dst;
uint16_t dport=htons(pkt->port_dst);
int nat_entry=-1;
for (int i=0; i<NAT_TAB_SIZE; i++) {
// if (pkt->proto==PROT_TCP || pkt->proto==PROT_UDP) {
if (pkt->ip_src == nattab[i].src_ip &&
pkt->ip_dst==nattab[i].dst_ip &&
pkt->port_src==nattab[i].src_port &&
pkt->port_dst==nattab[i].dst_port &&
nattab[i].proto==pkt->proto ) { /*print_log("[NAT_TCP] Found match...");*/ nat_entry=i; break;}
// }
}
if (nat_entry==-1) {// find oldest entry
int oldent=0;
uint32_t maxtime=0;
for (int i=0; i<NAT_TAB_SIZE; i++) {
if (nattab[i].status) continue;// не трогаем не разорванные TCP соединения
if (curtime-nattab[i].time>maxtime) { maxtime=curtime-nattab[i].time; oldent=i; }
}
nat_entry=oldent;
nattab[nat_entry].src_ip=pkt->ip_src;
nattab[nat_entry].dst_ip=pkt->ip_dst;
nattab[nat_entry].src_port=pkt->port_src;
nattab[nat_entry].dst_port=pkt->port_dst;
nattab[nat_entry].proto=pkt->proto;
}
nattab[nat_entry].time=curtime;
pkt->ip_dst=gnetif.ip_addr.addr;
pkt->port_dst=htons(NAT_DIVERT_PORT);
// print_log("[NAT_TCP] === forward pkt from %d.%d.%d.%d:%d to %d.%d.%d.%d:%d nat_entry %d proto %d", ip[0],ip[1],ip[2],ip[3], port, dip[0],dip[1],dip[2],dip[3], dport, nat_entry, pkt->proto);
return 0;
}
int backward_nat(struct ETH_QUEUE* block) {// пакет из интернета (т.е. LWIP стека) в локалку
struct ETH_PKT_HDR *pkt = (struct ETH_PKT_HDR *) block->pbuf->pbuf.payload;
if (pkt->ethertype != htons(0x800)) return -1;// no match
if (pkt->ip_src != gnetif.ip_addr.addr && pkt->port_src != htons(NAT_DIVERT_PORT))
return -1;// local dgram
if (pkt->proto != PROT_TCP && pkt->proto != PROT_UDP && pkt->proto != PROT_ICMP) return -1;
uint32_t curtime = xTaskGetTickCount();
int nat_entry = -1;
for (int i = 0; i < NAT_TAB_SIZE; i++) {
if (pkt->ip_dst == nattab[i].src_ip && pkt->port_dst == nattab[i].src_port &&
pkt->proto == nattab[i].proto) {
nat_entry = i;
break;
}
}
if (nat_entry == -1) return -1;// no match
pkt->ip_src = nattab[nat_entry].dst_ip;
pkt->port_src = nattab[nat_entry].dst_port;
uint8_t* ip=&pkt->ip_src;
uint16_t port=htons(pkt->port_src);
uint8_t* dip=&pkt->ip_dst;
uint16_t dport=htons(pkt->port_dst);
// print_log("[NAT_TCP] === backward pkt from %d.%d.%d.%d:%d to %d.%d.%d.%d:%d nat_entry %d proto %d", ip[0],ip[1],ip[2],ip[3], port, dip[0],dip[1],dip[2],dip[3], dport, nat_entry, pkt->proto);
return 0;
}
struct tcp_pcb* nat_tcp;
static void nat_close_so_conn(uint32_t idx) {
if (nattab[idx].status) {
shutdown(nattab[idx].socket, SHUT_RDWR);
nattab[idx].status=0;
}
// if (nattab[idx].status) { close(nattab[idx].socket); nattab[idx].status=0;}
}
static void nat_close_lw_conn(uint32_t idx) {
if (nattab[idx].pcb) {
uint32_t ptr=nattab[idx].index_begin;
while (ptr!=nattab[idx].index_end) {
if (nattab[idx].p[ptr]) {
tcp_recved(nattab[idx].pcb, nattab[idx].p[ptr]->tot_len);
pbuf_free(nattab[idx].p[ptr]);
nat_stat.pbuf_used--;
nattab[idx].p[ptr]=NULL;
}
ptr++;
if (ptr>=SNDQ_MAXLEN) ptr=0;
}
nattab[idx].offs=0;
nattab[idx].index_begin=ptr;
nat_stat.tcp_close++;
err_t e=tcp_shutdown(nattab[idx].pcb, 1, 1);
if (e==ERR_OK) {
tcp_abort(nattab[idx].pcb);
nattab[idx].pcb=NULL;
}
nattab[idx].pcb=NULL;
}
nattab[idx].txbuf_len=0;
}
_Noreturn static void NAT_Task( void* arg ) {// здесь обслуживаем передачу из LWIP в сокет
uint32_t sel_req=0;
LOCK_LWIP_CORE();
while (1) {
uint32_t act;
int maxfd=-1;
fd_set wfd;
FD_ZERO(&wfd);
for (int i = 0; i < NAT_TAB_SIZE; i++) {
if (nattab[i].status>0 ) {// descriptor is active
if (nattab[i].socket>maxfd) maxfd=nattab[i].socket;
if (nattab[i].index_begin!=nattab[i].index_end) { FD_SET(nattab[i].socket, &wfd); sel_req=1; }
}
}
fd_set rfd;
FD_ZERO(&rfd);
FD_SET(nat_task_pipe[0], &rfd);
if (maxfd<nat_task_pipe[0]) maxfd=nat_task_pipe[0];
UNLOCK_LWIP_CORE();
// struct timeval timeout={0,100*1000};// x0.1s потом ожно добавить еще один локальный сокет чтобы будить (добавить поток)
int res = select(maxfd+1, &rfd, &wfd, NULL, NULL /*&timeout*/);
LOCK_LWIP_CORE();
if (res == -1) continue;
if (FD_ISSET(nat_task_pipe[0], &rfd)) {// new socket
// print_log("[NAT_Task] pipe event");
char dummy;
read(nat_task_pipe[0], &dummy, 1);// recv from socket
}
for (int i = 0; i < NAT_TAB_SIZE; i++) {
if (nattab[i].status==0) continue;// дескриптор куда-то делся
if (FD_ISSET(nattab[i].socket, &wfd)) do {// socket ready for write data
// print_log("[NAT_Task] Write to tab %d", i);
struct pbuf *p=nattab[i].p[nattab[i].index_begin];
struct pbuf *p1=p;
uint32_t offs=nattab[i].offs;
int size=p->tot_len;
while(p1->next!=NULL && offs>=p1->len) {// SEEK to offs into pbuf chain
if (p1->next==NULL && p1->len!=size) { nat_stat.pbuf_broken++; size=p1->len; }
offs-=p1->len; size-=p1->len; p1=p->next;
}
int len=send(nattab[i].socket, (uint8_t*)p1->payload+offs, p->len-offs, MSG_DONTWAIT);
// print_log("[NAT_Task] tab %d send %d:%d bytes, %d sent", i, offs, p->len-offs, len);
if (len<0) {
if (errno == EAGAIN || errno == ENOBUFS) break;//
print_log("[NAT_Task] tab %d send error, close connection (err %d: %s)", i, errno, strerror(errno));
nattab[i].shutdown_req=1;
nat_close_so_conn(i);
nat_close_lw_conn(i);
break;
}
nattab[i].offs+=len;
if (nattab[i].offs<p->tot_len) { sel_req=1; break;}// not all sent
nattab[i].p[nattab[i].index_begin]=0;
nattab[i].index_begin++;
if (nattab[i].index_begin>=SNDQ_MAXLEN) nattab[i].index_begin=0;
nattab[i].offs=0;
tcp_recved(nattab[i].pcb, p->tot_len);
nat_stat.pbuf_used--;
pbuf_free(p);
// print_log("[NAT_Task] tab %d free pbuf", i);
} while(0);
}
}
}
_Noreturn static void NAT_RX_Task( void* arg ) {// здесь обслуживаем прием из сокетов и передачу в LWIP
uint32_t sel_req=0;
LOCK_LWIP_CORE();
while (1) {
uint32_t act;
int maxfd=-1;
fd_set rfd, efd;
FD_ZERO(&rfd); FD_ZERO(&efd);
for (int i = 0; i < NAT_TAB_SIZE; i++) {
if (nattab[i].status>0 ) {// descriptor is active
if (nattab[i].socket>maxfd) maxfd=nattab[i].socket;
FD_SET(nattab[i].socket, &rfd);
FD_SET(nattab[i].socket, &efd);
}
}
FD_SET(nat_rx_task_pipe[0], &rfd);
if (maxfd<nat_rx_task_pipe[0]) maxfd=nat_rx_task_pipe[0];
if (maxfd==-1) {
UNLOCK_LWIP_CORE();
usleep(100*1000);
LOCK_LWIP_CORE();
continue;
}
UNLOCK_LWIP_CORE();
// struct timeval timeout={0,100*1000};// x0.1s потом ожно добавить еще один локальный сокет чтобы будить (добавить поток)
int res = select(maxfd+1, &rfd, NULL, &efd, NULL /*&timeout*/);
LOCK_LWIP_CORE();
if (res == -1) continue;
if (FD_ISSET(nat_rx_task_pipe[0], &rfd)) {// new socket
// print_log("[NAT_rxTask] pipe event");
char dummy;
read(nat_rx_task_pipe[0], &dummy, 1);// recv from socket
}
for (int i = 0; i < NAT_TAB_SIZE; i++) {
if (nattab[i].status==0) continue;// дескриптор куда-то делся
if (FD_ISSET(nattab[i].socket, &efd)) {// error: close connection
print_log("[NAT_rxTask] tab %d select errorfd occurs, close connection (by remote host)", i);
nattab[i].shutdown_req=1;
nat_close_so_conn(i);
nat_close_lw_conn(i);
continue;// отключили сокет
}
if (FD_ISSET(nattab[i].socket, &rfd)) {// socket ready for read data
int rfd_cont=0;
do {
if (nattab[i].txbuf_len <= 0) {
int len = recv(nattab[i].socket, nattab[i].txbuf, sizeof(nattab[0].txbuf), MSG_DONTWAIT);// recv from socket
// print_log("[NAT_rxTask] tab %d recv %d bytes err %d %s", i, len, errno, strerror(errno));
if (len==0 && rfd_cont==0) {// connection shutdown request
print_log("[NAT_rxTask] tab %d shutdown connection", i);
nattab[i].shutdown_req=1;
nat_close_so_conn(i);
nat_close_lw_conn(i);
break;
}
rfd_cont++;
if (len<0) {
if (errno == EAGAIN) break;//
print_log("[NAT_rxTask] tab %d recv error, close connection (err %d: %s)", i, errno, strerror(errno));
nattab[i].shutdown_req=1;
nat_close_so_conn(i);
nat_close_lw_conn(i);
}
if (len < 1) { break; }// error recv data
nattab[i].txbuf_len=len;
}
if (nattab[i].txbuf_len > 0) {
err_t err=tcp_write(nattab[i].pcb, nattab[i].txbuf, nattab[i].txbuf_len, TCP_WRITE_FLAG_COPY);// write to lwip
if (err==ERR_OK) {
nattab[i].txbuf_len=0;
continue;
}
}
break;
} while(1);
}
}
}
}
static void nat_tcp_err(void *arg, err_t err) { // The pcb had an error and is already deallocated. The argument might still be valid (if != NULL).
if (arg) {
uint32_t num=(int)arg-1;
print_log("[NAT_Task] tab %d close connection (by local host)", num);
if (num<NAT_TAB_SIZE) {
nat_close_so_conn(num);
nattab[num].pcb=NULL;
}
}
}
static int nat_find_match(uint32_t ip, uint16_t port, uint8_t proto) {
for (int i = 0; i < NAT_TAB_SIZE; i++) {
if (ip == nattab[i].src_ip && port == nattab[i].src_port && proto == nattab[i].proto) return i;
}
return -1;
}
static err_t nat_tcp_sent(void *arg, struct tcp_pcb *pcb, u16_t len) {// Data has been sent and acknowledged by the remote host. This means that more data can be sent.
// TNotifyAdd( &tNotifyHandle, taskNOTIFY_NEW_DATA);
write(nat_task_pipe[1], "1",1);// notify for new data
return ERR_OK;
}
static err_t nat_tcp_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { // Data has been received on this pcb.
uint32_t nat_entry=(int)arg-1;
if ((err != ERR_OK) || (pcb == NULL) || (p == NULL)) {
print_log("[NAT_LWTCP_RECV1] closing connection by loacl side request: err=%d pcb=%d p=%d", err, pcb, p);
if (nat_entry<NAT_TAB_SIZE) {
nattab[nat_entry].shutdown_req=1;
nat_close_so_conn(nat_entry);
nat_close_lw_conn(nat_entry);
}
return ERR_VAL;
}
uint32_t* ip=&pcb->remote_ip.addr;
uint16_t port=htons(pcb->remote_port);
// print_log("[NAT_LWTCP_RECV3] nat_entry=%d rport=%d %d.%d.%d.%d", nat_entry, htons(port), (*ip)&0xff, (*ip>>8)&0xff, (*ip>>16)&0xff, (*ip>>24)&0xff);
if (nat_entry>=NAT_TAB_SIZE) goto recv_abrt;
if (*ip!=nattab[nat_entry].src_ip || port != nattab[nat_entry].src_port || nattab[nat_entry].proto != PROT_TCP) {nattab[nat_entry].errors++; goto recv_abrt; }
uint16_t idx=nattab[nat_entry].index_end;
if (idx>=SNDQ_MAXLEN) { nattab[nat_entry].errors++; goto recv_abrt; }
int idx_next=idx+1;
if (idx_next>=SNDQ_MAXLEN) idx_next=0;
if (idx_next==nattab[nat_entry].index_begin) { nattab[nat_entry].rx_ovf++; print_log("[NAT_LWTCP_RECV] RX_OVF: idx_b=%d idx_e=%d", nattab[nat_entry].index_begin, nattab[nat_entry].index_end ); goto recv_abrt; }
// print_log("[NAT_TCP] tab %d LWIP RECV %d/%d bytes", nat_entry, p->len, p->tot_len);
if (nattab[nat_entry].pcb!=pcb) { print_log("[NAT_TCP] PCB not match!!!!!!!!!!!!!!!!"); while(1);}
nattab[nat_entry].p[idx]=p;
nattab[nat_entry].index_end=idx_next;
nat_stat.pbuf_used++;
// TNotifyAdd( &tNotifyHandle, taskNOTIFY_NEW_DATA);
write(nat_task_pipe[1], "1",1);// notify for new data
// nattab[nat_entry].shutdown_req=1;
// nat_close_so_conn(nat_entry);
// nat_close_lw_conn(nat_entry);
return ERR_OK;
recv_abrt:
if (p) {
tcp_recved(pcb, p->tot_len);
pbuf_free(p);
}
return ERR_OK;
// return ERR_ABRT;
}
static err_t nat_accept_fn(void *arg, struct tcp_pcb *pcb, err_t err) {
// print_log("[NAT_TCP] === NEW connection callback");
if ((err != ERR_OK) || (pcb == NULL)) { return ERR_VAL; }
uint8_t* ip=(uint8_t*)&pcb->remote_ip.addr;
uint16_t port=pcb->remote_port;
print_log("[NAT_TCP] === NEW connecion from %d.%d.%d.%d:%d", ip[0],ip[1],ip[2],ip[3], port);
int entry=nat_find_match(pcb->remote_ip.addr, htons(pcb->remote_port), PROT_TCP);
if (entry<0) return ERR_VAL;
tcp_arg(pcb, (void*)(entry+1));// arg for this TCP connection
int s=socket(AF_INET, SOCK_STREAM, 0);
if (s==-1) { print_log("[NAT_TCP] tab %d socket allocation err", entry); return ERR_VAL; }
int status = fcntl(s, F_SETFL, fcntl(s, F_GETFL, 0) | O_NONBLOCK);
if (status==-1) { close(s); print_log("[NAT_TCP] tab %d FCNTL error", entry); return ERR_VAL; }
int keepcnt = 8;
int keepidle = 2;
int keepintvl = 2;
int nodelay = 1;
int syncnt = 3;
setsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt, sizeof(int));
setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle, sizeof(int));
setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl, sizeof(int));
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(int));
setsockopt(s, IPPROTO_TCP, TCP_SYNCNT, &syncnt, sizeof(int));
tcp_nagle_disabled(pcb);
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = nattab[entry].dst_ip;
servaddr.sin_port = nattab[entry].dst_port;
ip=(uint8_t*)&servaddr.sin_addr.s_addr;
port=htons(servaddr.sin_port);
print_log("[NAT_TCP] === connecion to %d.%d.%d.%d:%d", ip[0],ip[1],ip[2],ip[3], port);
int r=connect(s, (struct sockaddr*)&servaddr, sizeof(servaddr));
if (r != 0) if (errno != EINPROGRESS)
{
print_log("[NAT_TCP] tab %d can not connect: %d", entry, errno);
close(s);
return ERR_VAL;
}
nattab[entry].socket=s;
nattab[entry].status=1;
nattab[entry].index_begin=0;
nattab[entry].index_end=0;
nattab[entry].offs=0;
nattab[entry].shutdown_req=0;
nattab[entry].pcb=pcb;
print_log("[NAT_TCP] tab %d new remote TCP conn", entry);
/* Set up the various callback functions */
tcp_recv(pcb, nat_tcp_recv);
tcp_err(pcb, nat_tcp_err);
// tcp_poll(pcb, nat_tcp_poll, HTTPD_POLL_INTERVAL);
tcp_sent(pcb, nat_tcp_sent);
nat_stat.tcp_new++;
write(nat_task_pipe[1], "1",1);// notify for new connection
write(nat_rx_task_pipe[1], "1",1);// notify for new connection
return ERR_OK;
}
void eth_nat_init() {
int ret=pipe2(&nat_task_pipe, O_NONBLOCK);
ret=pipe2(&nat_rx_task_pipe, O_NONBLOCK);
if (ret) return;
fcntl(nat_task_pipe[0], F_SETFL, O_NONBLOCK);
fcntl(nat_rx_task_pipe[0], F_SETFL, O_NONBLOCK);
fcntl(nat_task_pipe[1], F_SETFL, O_NONBLOCK);
fcntl(nat_rx_task_pipe[1], F_SETFL, O_NONBLOCK);
// TNotifyCreate(&tNotifyHandle);
TaskCreate (NAT_Task, &tnatHandle);
TaskCreate (NAT_RX_Task, &tnatRXHandle);
pthread_t tstats;
TaskCreate (calc_stats, &tstats);
nat_tcp=tcp_new_ip_type(IPADDR_TYPE_V4);
if (nat_tcp==NULL) return;
tcp_bind(nat_tcp, IP_ANY_TYPE, NAT_DIVERT_PORT);
err_t err;
nat_tcp=tcp_listen_with_backlog_and_err(nat_tcp, 10, &err);
if (nat_tcp==NULL) { print_log("[NAT_TCP] === NAT tcp listen failed (err %d)", err); return; }
tcp_accept(nat_tcp, nat_accept_fn);
// print_log("[NAT_TCP] === NAT INIT");
}
+40
View File
@@ -0,0 +1,40 @@
#define NAT_TAB_SIZE 16
#define SNDQ_MAXLEN 100
struct NAT_TAB {
uint32_t src_ip;// порядок байт в сетевом формате
uint32_t dst_ip;// порядок байт в сетевом формате
uint16_t src_port;// порядок байт в сетевом формате
uint16_t dst_port;// порядок байт в сетевом формате
uint16_t proto;
uint32_t time;
struct pbuf* p[SNDQ_MAXLEN];// очередь приема с lwip
uint8_t txbuf[1500];// на передачу в lwip
uint16_t txbuf_len;
struct tcp_pcb *pcb;// null - free
uint32_t index_begin;
uint32_t index_end;
uint32_t status;// 0-free, 1-active (for TCP-based entries)
int socket;
uint32_t offs;
uint32_t errors;
uint32_t rx_ovf;
uint32_t shutdown_req;// 1 - waiting for shutdown sockets
};
struct NAT_STAT {
uint32_t pbuf_broken;
uint32_t tcp_new;
uint32_t tcp_close;
uint32_t pbuf_used;
uint32_t lw_conn_used;
uint32_t so_conn_used;
};
extern struct NAT_STAT nat_stat;
int forward_nat(struct ETH_QUEUE* block);
int backward_nat(struct ETH_QUEUE* block);
void eth_nat_init();
+34
View File
@@ -0,0 +1,34 @@
#include "eth_mem.h"
#include "eth_queue.h"
void add_to_custom_queue(struct pbuf* p, struct ETH_Q* q) {
p->next = NULL;
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
if (q->q_len>=q->q_len_max) {// очередь уже полна. дропаем пакет.
q->lost++;
ETH_MEM_UNPROTECT();
pbuf_free(p);
return;
}
if (q->q_end) q->q_end->next=p; else q->q_begin=p;// этот элемент приписываем к концу очереди
q->q_end=p;// конечным элементом ставим этот элемент
q->q_len++;
if (q->q_len_max<q->q_len) q->q_len_max=q->q_len;
ETH_MEM_UNPROTECT();
}
struct pbuf* get_from_custom_queue(struct ETH_Q* q) {
ETH_MEM_DECL_PROTECT();
ETH_MEM_PROTECT();
struct pbuf* p=(struct pbuf*)q->q_begin;
if (p==NULL) { ETH_MEM_UNPROTECT(); return NULL; }
struct pbuf* next_pbuf=p->next;
q->q_begin=next_pbuf;
if (next_pbuf == NULL) q->q_end = NULL;
if (q->q_len==0) EM_ASSERT(7);// ASSERT: сбой подсчета размера очереди.
q->q_len--;
ETH_MEM_UNPROTECT();
p->next=NULL;
return p;
}
+14
View File
@@ -0,0 +1,14 @@
struct ETH_Q {
struct pbuf* q_begin;
struct pbuf* q_end;
uint32_t q_len;
uint32_t q_len_max;
uint32_t lost;
};
// добавить ETH_PBUF p в очередь q
void add_to_custom_queue(struct pbuf* p, struct ETH_Q* q);
// возврат - NULL - очередь пуста; иначе pbuf
struct pbuf* get_from_custom_queue(struct ETH_Q* q);
+124
View File
@@ -0,0 +1,124 @@
#include <stdint.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "eth_mem.h"
#include "eth_router.h"
#include "eth_router_cfg.h"
#include "eth_nat.h"
struct ETH_ROUTER_STATS eth_router_stats;
struct ETH_QUEUEPOOL_CTRL xeth_queuepool_ctrl;
struct ETH_QUEUE xeth_queuepool[ETH_MEM_BUFS_CNT] ETH_MEM_ALIGN;
struct ETH_PBUF_CTRL xeth_pbuf_ctrl;
struct ETH_PBUF eth_pbuf[ETH_PBUFS_CNT];
uint8_t eth_pbuf_mem[ETH_PBUFS_CNT*ETH_MEM_BUF_SIZE];// граница элементов кратна 32 байтам. иначе будут проблемки с кешем.
struct ETH_NETIF eth_netif_array[ETH_NETIFS];
void eth_router_init() {
eth_router_add_bridge(&xeth_queuepool_ctrl, xeth_queuepool, ETH_MEM_BUFS_CNT, &xeth_pbuf_ctrl, eth_pbuf, eth_pbuf_mem, ETH_PBUFS_CNT, eth_netif_array, ETH_NETIFS);
eth_router_start_task(&xeth_queuepool_ctrl);
}
#define ETHTYPE_IPV4 0x0800
#define ETHTYPE_IPV6 0x86DD
#define ETHTYPE_ARP 0x0806
#define ETHTYPE_ADP 0x8777// braodcast топологии
#define ETHTYPE_DBG 0x8778// unicast diagram
#define ETHTYPE_CONTROLS 0x8779// controls, terminal, gui controls
void sprint_pkt(char* pkt, int pkt_len) {
char textbuf[1000];
char textptr=0;
textptr+=sprintf(textbuf+textptr,"DMAC=%02X:%02X:%02X:%02X:%02X:%02X ",pkt[0],pkt[1],pkt[2],pkt[3],pkt[4],pkt[5]);
textptr+=sprintf(textbuf+textptr,"SMAC=%02X:%02X:%02X:%02X:%02X:%02X ",pkt[6],pkt[7],pkt[8],pkt[9],pkt[10],pkt[11]);
uint16_t ethertype=(pkt[12]<<8)+pkt[13];
textptr+=sprintf(textbuf+textptr,"ET=%04X ",ethertype);
if (ethertype == ETHTYPE_ARP) {
textptr+=sprintf(textbuf+textptr,"[ARP] ");
}
if (ethertype == ETHTYPE_IPV4) {
textptr+=sprintf(textbuf+textptr,"[IP4] ");
}
if (ethertype == ETHTYPE_ADP) {
textptr+=sprintf(textbuf+textptr,"[ADP] ");
}
if (ethertype == ETHTYPE_DBG) {
textptr+=sprintf(textbuf+textptr,"[DBG] ");
}
if (ethertype == ETHTYPE_CONTROLS) {
textptr+=sprintf(textbuf+textptr,"[CTR] ");
}
if (ethertype == ETHTYPE_ADP || ethertype == ETHTYPE_DBG || ethertype == ETHTYPE_CONTROLS) {
}
textptr+=sprintf(textbuf+textptr,"LEN=%d ",pkt_len);
print_log("%s",textbuf);
}
int prev_num;
void eth_route_block(struct ETH_QUEUE* block) {
if (block->pbuf->pbuf.ref==0) EM_ASSERT(20);
int pbuf_num=(block->pbuf-eth_pbuf);
uint32_t src_netif=block->pbuf->pbuf.if_idx;
// sprint_pkt(block->pbuf->pbuf.payload, block->pbuf->pbuf.len);
/*if (src_netif == LWIP_NETIF_ID) {
print_log("Route pbuf from lwip");
sprint_pkt(block->pbuf->pbuf.payload, block->pbuf->pbuf.len);
}*/
if (src_netif>=ETH_NETIFS) EM_ASSERT(21);// assert: invalid netif
if (src_netif==0) EM_ASSERT(22);// assert: invalid netif
if (src_netif==TEST_NETIF_ID) eth_router_stats.in_test++;
if (src_netif==BLE_NETIF_ID) eth_router_stats.in_ble++;
if (eth_netif_array[src_netif].if_up==0) {// src interface is down: drop packet & exit
block->pool->eth_netif_array[src_netif].dgrams_lost++;
eth_pbuf_free_request(block->pbuf);
eth_queue_entry_free(block);
print_log("interface (%d) is not up, dropping dgram ",src_netif);
return;
}
// block->pool->eth_netif_array[src_netif].dgrams_lost++;
uint32_t dst_netif=src_netif;
if (src_netif == BLE_NETIF_ID) {
forward_nat(block);
dst_netif=LWIP_NETIF_ID;
}
if (src_netif == LWIP_NETIF_ID) {
backward_nat(block);
dst_netif=BLE_NETIF_ID;
}
if (dst_netif>=ETH_NETIFS) EM_ASSERT(23);// assert: invalid netif
if (dst_netif==0) {
eth_pbuf_free_request(block->pbuf);
eth_queue_entry_free(block);
return;
}
eth_add_packet_to_output_queue(block, &block->pool->eth_netif_array[dst_netif]);
}
+58
View File
@@ -0,0 +1,58 @@
#pragma once
#include "eth_mem.h"
struct __attribute__((__packed__)) MAC_ADDR {
uint32_t mac32;
uint16_t mac16;
};
struct __attribute__((__packed__)) ETH_PKT_HDR {
struct MAC_ADDR dst_mac;
struct MAC_ADDR src_mac;
uint16_t ethertype;
uint8_t tos_hdrl;
uint8_t dscp;
uint16_t len;
uint16_t id;
uint16_t frag_offs;
uint8_t ttl;
uint8_t proto;
uint16_t hdr_csum;
uint32_t ip_src;
uint32_t ip_dst;
uint16_t port_src;// tcp/udp hdr
uint16_t port_dst;
};
struct MAC_LOOKUP_TAB {
struct MAC_ADDR mac;
uint16_t time_upd;
uint8_t if_idx;
};
struct ETH_ROUTER_STATS {
uint32_t in_test;
uint32_t in_ble;
uint32_t out_if_not_found;
uint32_t test_err;
};
extern struct ETH_ROUTER_STATS eth_router_stats;
void eth_route_block(struct ETH_QUEUE* block);
uint32_t mac_search(struct MAC_ADDR mac);
// проинициализировать мост по умолчанию (запускает eth_router_add_bridge с дефолтным пулом)
void eth_router_init();
void notify_eth_ble_send_queue_update();
void notify_eth_uart_send_queue_update();
//extern struct ETH_QUEUE xeth_queuepool[ETH_MEM_BUFS_CNT];
extern struct ETH_QUEUEPOOL_CTRL xeth_queuepool_ctrl;
extern struct ETH_QUEUE xeth_queuepool[ETH_MEM_BUFS_CNT];
extern struct ETH_PBUF_CTRL xeth_pbuf_ctrl;
extern struct ETH_PBUF eth_pbuf[ETH_PBUFS_CNT];
extern uint8_t eth_pbuf_mem[ETH_PBUFS_CNT*ETH_MEM_BUF_SIZE];
extern struct ETH_NETIF eth_netif_array[ETH_NETIFS];
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#define ETH_MEM_BUFS_CNT 100 // количество буферов (занимают ETH_MEM_BUF_SIZE байт)
#define ETH_PBUFS_CNT 400// (занимают один pbuf)
#define ETH_MEM_BUF_SIZE 1600// размер данных ethernet пакета (начиная с мак адресов)
#define ETH_NETIFS 4// макс. количество интерфейсов
// номер интерфейса в роутере (начиная с единицы)
#define LWIP_NETIF_ID 1
#define TEST_NETIF_ID 2
#define BLE_NETIF_ID 3
// Зармеры исходящих очередей на интерфейсы
#define LWIP_NETIF_QLEN 20
#define UART_NETIF_QLEN 20
#define BLE_NETIF_QLEN 20
#define IN_BLE_NETIF_QLEN_THR 3
#define IN_UART_NETIF_QLEN_THR 3
+138
View File
@@ -0,0 +1,138 @@
#include "stdint.h"
uint8_t imageCubes[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xe3, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xf1, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x60, 0xff, 0xff, 0xff, 0xff, 0x00, 0x03, 0xf0, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf8, 0xe0, 0xff, 0xff, 0xff, 0xf0, 0xfe, 0x00, 0xe0, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf1, 0xe0, 0x7f, 0xff, 0xff, 0xf0, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe1, 0xc0, 0x7f, 0xff, 0xff, 0xf2, 0x7e, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe1, 0xd8, 0x7f, 0xff, 0xff, 0xf1, 0x30, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xc1, 0xb8, 0x3f, 0xff, 0xff, 0xf0, 0xf8, 0x00, 0x07, 0xc7, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x78, 0x3f, 0xff, 0xff, 0xf0, 0x7c, 0x00, 0x0f, 0xe3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x70, 0x1f, 0xff, 0xff, 0xfc, 0x7e, 0x00, 0x0f, 0xe1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0xf0, 0x1f, 0xff, 0xff, 0xfc, 0x3f, 0xf8, 0x03, 0xc1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x00, 0xee, 0x1f, 0xff, 0xff, 0xfe, 0x1f, 0xfc, 0x00, 0x0f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x5e, 0x1f, 0xff, 0xff, 0xfe, 0x1f, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf9, 0x80, 0x1e, 0x3f, 0xff, 0xff, 0xfe, 0x0f, 0xf0, 0x1f, 0xe0, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xf3, 0x80, 0x3c, 0x3f, 0xff, 0xff, 0xfe, 0x07, 0xe3, 0xfc, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xe7, 0x80, 0x3c, 0x7d, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xe7, 0x80, 0x38, 0xe0, 0x7f, 0xcf, 0xfd, 0x63, 0xf8, 0x00, 0x38, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xc7, 0x00, 0x10, 0xc1, 0x1f, 0xe7, 0xff, 0x77, 0xf0, 0x00, 0x7c, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xc6, 0xc0, 0x01, 0x00, 0x4e, 0x73, 0xff, 0x77, 0xf0, 0x00, 0xfc, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xc1, 0xe0, 0x02, 0x0e, 0x33, 0x3b, 0xff, 0x77, 0xee, 0x00, 0xf8, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xc1, 0xc0, 0x06, 0x1f, 0x7d, 0x9d, 0xff, 0x73, 0xff, 0x01, 0xf8, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe3, 0xc0, 0x0c, 0x3f, 0xbe, 0x45, 0xff, 0xfb, 0xff, 0x00, 0xf0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe3, 0x80, 0x18, 0x7f, 0xbf, 0x90, 0xff, 0xf3, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe3, 0xb0, 0x30, 0x7f, 0xbf, 0xe8, 0xff, 0xf3, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x70, 0x60, 0x7f, 0x3f, 0xf2, 0x7f, 0xf3, 0xfe, 0x18, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0xf0, 0x40, 0x3e, 0x1f, 0xfd, 0xff, 0xf3, 0xd8, 0x7c, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf0, 0xf0, 0x80, 0x00, 0x0f, 0xfe, 0x7f, 0xf3, 0xe0, 0xfc, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf1, 0xe1, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf3, 0xf8, 0xfc, 0x00, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf1, 0xc2, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf3, 0xf8, 0xfc, 0x01, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x84, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf3, 0xfe, 0xf8, 0xf1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x08, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf3, 0xff, 0x21, 0xf1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x10, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf3, 0xff, 0xc3, 0xf1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x30, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf3, 0xff, 0xf3, 0xf3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0x60, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0xc0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xbf, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf0, 0x00, 0x1f, 0xdf, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xdf, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf8, 0x0c, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
uint8_t imageWolf[] = {
0xff, 0xff, 0xff, 0x8f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xf3, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x3f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xf9, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x7f, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xfe, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfc, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf9, 0x80, 0x7f, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf9, 0xea, 0x9f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xf8, 0xd5, 0x7f, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfb, 0x29, 0x54, 0x5f, 0x9f, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xb1, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfa, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x5f, 0xc0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x07, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xe0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x01, 0xb0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xa8, 0x60, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xfd, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfa, 0x37, 0x20, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x01, 0xe0, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x05, 0xe0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0xd0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3e, 0xe0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x00, 0x7f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xfd, 0xf0, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x0c, 0x7f, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc4, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x0f, 0x1f, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf7, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x7f, 0xfa, 0xff, 0xef, 0xff, 0xff, 0xff, 0x28, 0x0b, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfd, 0xff, 0xdf, 0xff, 0xf7, 0xff, 0xff, 0xfe, 0xc0, 0x2b, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xff, 0xfd, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0x97, 0xff, 0xfb, 0xff, 0xff, 0xed, 0x4a, 0x95, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xd2, 0xbf, 0xfa, 0xbf, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xd3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xd7, 0xff, 0xfd, 0x3f, 0xff, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xf4, 0x9f, 0xff, 0x7b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x9d, 0x9f, 0xff, 0x67, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0x4c, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xbf, 0xff, 0xc9, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xb8, 0x7f, 0xff, 0xc3, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xfc, 0x7f, 0xff, 0x86, 0x31, 0x7f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xfe, 0x3f, 0xff, 0x1f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0x3f, 0xff, 0x3f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xbf, 0xff, 0x3f, 0x3f, 0xd7, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0x7f, 0xfa, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd5, 0xff, 0xff, 0xef, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xfe, 0x0f, 0xff,
0xff, 0xff, 0xff, 0xef, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xa9, 0x17, 0xef, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xee, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xf1, 0xbf, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xfc, 0x4f, 0xff,
0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7e, 0x17, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8b, 0xc7, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xb3, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x50, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x93, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0f, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xf7, 0x47, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xfb, 0xa3, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xfe, 0xd3, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0x8f, 0xff, 0xff, 0xff, 0x5f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x9f, 0xbf,
0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xfe, 0x1e, 0xef, 0xbf, 0xe7, 0xf7, 0xee, 0xdf,
0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x80, 0x80, 0xff, 0x27, 0xff, 0xfd, 0xff, 0xe2, 0x6f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xf8, 0x0f, 0xcf, 0xd7, 0xff, 0xff, 0xff, 0xf1, 0x37,
0xff, 0xff, 0xff, 0xfe, 0xc7, 0xf9, 0x9f, 0xff, 0xbf, 0x9b, 0xf7, 0xff, 0xfb, 0xff, 0xf8, 0x13,
0xff, 0xff, 0xff, 0xff, 0xdf, 0xe8, 0xcb, 0xfe, 0x1e, 0x1b, 0xbd, 0xff, 0xff, 0xff, 0xf4, 0x1b,
0xff, 0xff, 0xff, 0xff, 0x1f, 0xdc, 0xe3, 0xfd, 0x8f, 0x1d, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x83,
0xff, 0xff, 0xff, 0xff, 0x1f, 0xdc, 0xe3, 0xfd, 0x8f, 0x1d, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x83,
0xff, 0xff, 0xff, 0xff, 0x1f, 0xdc, 0xe3, 0xfd, 0x8f, 0x1d, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x83,
};
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+115
View File
@@ -0,0 +1,115 @@
/**
* @file
* Error Management module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/err.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/errno.h"
#if !NO_SYS
/** Table to quickly map an lwIP error (err_t) to a socket error
* by using -err as an index */
static const int err_to_errno_table[] = {
0, /* ERR_OK 0 No error, everything OK. */
ENOMEM, /* ERR_MEM -1 Out of memory error. */
ENOBUFS, /* ERR_BUF -2 Buffer error. */
EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */
EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */
EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
EINVAL, /* ERR_VAL -6 Illegal value. */
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
EADDRINUSE, /* ERR_USE -8 Address in use. */
EALREADY, /* ERR_ALREADY -9 Already connecting. */
EISCONN, /* ERR_ISCONN -10 Conn already established.*/
ENOTCONN, /* ERR_CONN -11 Not connected. */
-1, /* ERR_IF -12 Low-level netif error */
ECONNABORTED, /* ERR_ABRT -13 Connection aborted. */
ECONNRESET, /* ERR_RST -14 Connection reset. */
ENOTCONN, /* ERR_CLSD -15 Connection closed. */
EIO /* ERR_ARG -16 Illegal argument. */
};
int
err_to_errno(err_t err)
{
if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_to_errno_table))) {
return EIO;
}
return err_to_errno_table[-err];
}
#endif /* !NO_SYS */
#ifdef LWIP_DEBUG
static const char *err_strerr[] = {
"Ok.", /* ERR_OK 0 */
"Out of memory error.", /* ERR_MEM -1 */
"Buffer error.", /* ERR_BUF -2 */
"Timeout.", /* ERR_TIMEOUT -3 */
"Routing problem.", /* ERR_RTE -4 */
"Operation in progress.", /* ERR_INPROGRESS -5 */
"Illegal value.", /* ERR_VAL -6 */
"Operation would block.", /* ERR_WOULDBLOCK -7 */
"Address in use.", /* ERR_USE -8 */
"Already connecting.", /* ERR_ALREADY -9 */
"Already connected.", /* ERR_ISCONN -10 */
"Not connected.", /* ERR_CONN -11 */
"Low-level netif error.", /* ERR_IF -12 */
"Connection aborted.", /* ERR_ABRT -13 */
"Connection reset.", /* ERR_RST -14 */
"Connection closed.", /* ERR_CLSD -15 */
"Illegal argument." /* ERR_ARG -16 */
};
/**
* Convert an lwip internal error to a string representation.
*
* @param err an lwip internal err_t
* @return a string representation for err
*/
const char *
lwip_strerr(err_t err)
{
if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_strerr))) {
return "Unknown error.";
}
return err_strerr[-err];
}
#endif /* LWIP_DEBUG */
+102
View File
@@ -0,0 +1,102 @@
/**
* @file
* Interface Identification APIs from:
* RFC 3493: Basic Socket Interface Extensions for IPv6
* Section 4: Interface Identification
*
* @defgroup if_api Interface Identification API
* @ingroup socket
*/
/*
* Copyright (c) 2017 Joel Cunningham, Garmin International, Inc. <joel.cunningham@garmin.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Joel Cunningham <joel.cunningham@me.com>
*
*/
#include "lwip/opt.h"
#if LWIP_SOCKET
#include "lwip/errno.h"
#include "lwip/if_api.h"
#include "lwip/netifapi.h"
#include "lwip/priv/sockets_priv.h"
/**
* @ingroup if_api
* Maps an interface index to its corresponding name.
* @param ifindex interface index
* @param ifname shall point to a buffer of at least {IF_NAMESIZE} bytes
* @return If ifindex is an interface index, then the function shall return the
* value supplied in ifname, which points to a buffer now containing the interface name.
* Otherwise, the function shall return a NULL pointer.
*/
char *
lwip_if_indextoname(unsigned int ifindex, char *ifname)
{
#if LWIP_NETIF_API
if (ifindex <= 0xff) {
err_t err = netifapi_netif_index_to_name((u8_t)ifindex, ifname);
if (!err && ifname[0] != '\0') {
return ifname;
}
}
#else /* LWIP_NETIF_API */
LWIP_UNUSED_ARG(ifindex);
LWIP_UNUSED_ARG(ifname);
#endif /* LWIP_NETIF_API */
set_errno(ENXIO);
return NULL;
}
/**
* @ingroup if_api
* Returs the interface index corresponding to name ifname.
* @param ifname Interface name
* @return The corresponding index if ifname is the name of an interface;
* otherwise, zero.
*/
unsigned int
lwip_if_nametoindex(const char *ifname)
{
#if LWIP_NETIF_API
err_t err;
u8_t idx;
err = netifapi_netif_name_to_index(ifname, &idx);
if (!err) {
return idx;
}
#else /* LWIP_NETIF_API */
LWIP_UNUSED_ARG(ifname);
#endif /* LWIP_NETIF_API */
return 0; /* invalid index */
}
#endif /* LWIP_SOCKET */
+669
View File
@@ -0,0 +1,669 @@
/**
* @file
* Sequential API Main thread module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if !NO_SYS /* don't build if not configured for use in lwipopts.h */
#include "lwip/priv/tcpip_priv.h"
#include "lwip/sys.h"
#include "lwip/memp.h"
#include "lwip/mem.h"
#include "lwip/init.h"
#include "lwip/ip.h"
#include "lwip/pbuf.h"
#include "lwip/etharp.h"
#include "netif/ethernet.h"
#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name)
#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name)
#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM)
#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
/* global variables */
static tcpip_init_done_fn tcpip_init_done;
static void *tcpip_init_done_arg;
static sys_mbox_t tcpip_mbox;
#if LWIP_TCPIP_CORE_LOCKING
/** The global semaphore to lock the stack. */
sys_mutex_t lock_tcpip_core;
#endif /* LWIP_TCPIP_CORE_LOCKING */
static void tcpip_thread_handle_msg(struct tcpip_msg *msg);
#if !LWIP_TIMERS
/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */
#define TCPIP_MBOX_FETCH(mbox, msg) sys_mbox_fetch(mbox, msg)
#else /* !LWIP_TIMERS */
/* wait for a message, timeouts are processed while waiting */
#define TCPIP_MBOX_FETCH(mbox, msg) tcpip_timeouts_mbox_fetch(mbox, msg)
/**
* Wait (forever) for a message to arrive in an mbox.
* While waiting, timeouts are processed.
*
* @param mbox the mbox to fetch the message from
* @param msg the place to store the message
*/
static void
tcpip_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
{
u32_t sleeptime, res;
again:
LWIP_ASSERT_CORE_LOCKED();
sleeptime = sys_timeouts_sleeptime();
if (sleeptime == SYS_TIMEOUTS_SLEEPTIME_INFINITE) {
UNLOCK_TCPIP_CORE();
sys_arch_mbox_fetch(mbox, msg, 0);
LOCK_TCPIP_CORE();
return;
} else if (sleeptime == 0) {
sys_check_timeouts();
/* We try again to fetch a message from the mbox. */
goto again;
}
UNLOCK_TCPIP_CORE();
res = sys_arch_mbox_fetch(mbox, msg, sleeptime);
LOCK_TCPIP_CORE();
if (res == SYS_ARCH_TIMEOUT) {
/* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred
before a message could be fetched. */
sys_check_timeouts();
/* We try again to fetch a message from the mbox. */
goto again;
}
}
#endif /* !LWIP_TIMERS */
/**
* The main lwIP thread. This thread has exclusive access to lwIP core functions
* (unless access to them is not locked). Other threads communicate with this
* thread using message boxes.
*
* It also starts all the timers to make sure they are running in the right
* thread context.
*
* @param arg unused argument
*/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
SemaphoreHandle_t ipSemaphore = NULL;
static void
tcpip_thread(void *arg)
{
struct tcpip_msg *msg;
LWIP_UNUSED_ARG(arg);
ipSemaphore = xSemaphoreCreateMutex();
xSemaphoreGive( ipSemaphore );
LWIP_MARK_TCPIP_THREAD();
LOCK_TCPIP_CORE();
if (tcpip_init_done != NULL) {
tcpip_init_done(tcpip_init_done_arg);
}
while (1) { /* MAIN Loop */
LWIP_TCPIP_THREAD_ALIVE();
/* wait for a message, timeouts are processed while waiting */
TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg);
if (msg == NULL) {
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
LWIP_ASSERT("tcpip_thread: invalid message", 0);
continue;
}
if( xSemaphoreTake( ipSemaphore, ( TickType_t ) 0 ) ) {
tcpip_thread_handle_msg(msg);
xSemaphoreGive( ipSemaphore );
}
}
}
/* Handle a single tcpip_msg
* This is in its own function for access by tests only.
*/
static void
tcpip_thread_handle_msg(struct tcpip_msg *msg)
{
switch (msg->type) {
#if !LWIP_TCPIP_CORE_LOCKING
case TCPIP_MSG_API:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
msg->msg.api_msg.function(msg->msg.api_msg.msg);
break;
case TCPIP_MSG_API_CALL:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg));
msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg);
sys_sem_signal(msg->msg.api_call.sem);
break;
#endif /* !LWIP_TCPIP_CORE_LOCKING */
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
case TCPIP_MSG_INPKT:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
if (msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif) != ERR_OK) {
pbuf_free(msg->msg.inp.p);
}
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
break;
#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
case TCPIP_MSG_TIMEOUT:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
case TCPIP_MSG_UNTIMEOUT:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
case TCPIP_MSG_CALLBACK:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
msg->msg.cb.function(msg->msg.cb.ctx);
memp_free(MEMP_TCPIP_MSG_API, msg);
break;
case TCPIP_MSG_CALLBACK_STATIC:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
msg->msg.cb.function(msg->msg.cb.ctx);
break;
default:
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
LWIP_ASSERT("tcpip_thread: invalid message", 0);
break;
}
}
#ifdef TCPIP_THREAD_TEST
/** Work on queued items in single-threaded test mode */
int
tcpip_thread_poll_one(void)
{
int ret = 0;
struct tcpip_msg *msg;
if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_ARCH_TIMEOUT) {
LOCK_TCPIP_CORE();
if (msg != NULL) {
tcpip_thread_handle_msg(msg);
ret = 1;
}
UNLOCK_TCPIP_CORE();
}
return ret;
}
#endif
/**
* Pass a received packet to tcpip_thread for input processing
*
* @param p the received packet
* @param inp the network interface on which the packet was received
* @param input_fn input function to call
*/
err_t
tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUT
err_t ret;
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp));
LOCK_TCPIP_CORE();
ret = input_fn(p, inp);
UNLOCK_TCPIP_CORE();
return ret;
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
struct tcpip_msg *msg;
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_INPKT;
msg->msg.inp.p = p;
msg->msg.inp.netif = inp;
msg->msg.inp.input_fn = input_fn;
if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) {
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
return ERR_MEM;
}
return ERR_OK;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
}
/**
* @ingroup lwip_os
* Pass a received packet to tcpip_thread for input processing with
* ethernet_input or ip_input. Don't call directly, pass to netif_add()
* and call netif->input().
*
* @param p the received packet, p->payload pointing to the Ethernet header or
* to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
* NETIF_FLAG_ETHERNET flags)
* @param inp the network interface on which the packet was received
*/
err_t
tcpip_input(struct pbuf *p, struct netif *inp)
{
#if LWIP_ETHERNET
if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
return tcpip_inpkt(p, inp, ethernet_input);
} else
#endif /* LWIP_ETHERNET */
return tcpip_inpkt(p, inp, ip_input);
}
/**
* @ingroup lwip_os
* Call a specific function in the thread context of
* tcpip_thread for easy access synchronization.
* A function called in that way may access lwIP core code
* without fearing concurrent access.
* Blocks until the request is posted.
* Must not be called from interrupt context!
*
* @param function the function to call
* @param ctx parameter passed to f
* @return ERR_OK if the function was called, another err_t if not
*
* @see tcpip_try_callback
*/
err_t
tcpip_callback(tcpip_callback_fn function, void *ctx)
{
struct tcpip_msg *msg;
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_CALLBACK;
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
sys_mbox_post(&tcpip_mbox, msg);
return ERR_OK;
}
/**
* @ingroup lwip_os
* Call a specific function in the thread context of
* tcpip_thread for easy access synchronization.
* A function called in that way may access lwIP core code
* without fearing concurrent access.
* Does NOT block when the request cannot be posted because the
* tcpip_mbox is full, but returns ERR_MEM instead.
* Can be called from interrupt context.
*
* @param function the function to call
* @param ctx parameter passed to f
* @return ERR_OK if the function was called, another err_t if not
*
* @see tcpip_callback
*/
err_t
tcpip_try_callback(tcpip_callback_fn function, void *ctx)
{
struct tcpip_msg *msg;
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_CALLBACK;
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) {
memp_free(MEMP_TCPIP_MSG_API, msg);
return ERR_MEM;
}
return ERR_OK;
}
#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
/**
* call sys_timeout in tcpip_thread
*
* @param msecs time in milliseconds for timeout
* @param h function to be called on timeout
* @param arg argument to pass to timeout function h
* @return ERR_MEM on memory error, ERR_OK otherwise
*/
err_t
tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
{
struct tcpip_msg *msg;
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_TIMEOUT;
msg->msg.tmo.msecs = msecs;
msg->msg.tmo.h = h;
msg->msg.tmo.arg = arg;
sys_mbox_post(&tcpip_mbox, msg);
return ERR_OK;
}
/**
* call sys_untimeout in tcpip_thread
*
* @param h function to be called on timeout
* @param arg argument to pass to timeout function h
* @return ERR_MEM on memory error, ERR_OK otherwise
*/
err_t
tcpip_untimeout(sys_timeout_handler h, void *arg)
{
struct tcpip_msg *msg;
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return ERR_MEM;
}
msg->type = TCPIP_MSG_UNTIMEOUT;
msg->msg.tmo.h = h;
msg->msg.tmo.arg = arg;
sys_mbox_post(&tcpip_mbox, msg);
return ERR_OK;
}
#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
/**
* Sends a message to TCPIP thread to call a function. Caller thread blocks on
* on a provided semaphore, which ist NOT automatically signalled by TCPIP thread,
* this has to be done by the user.
* It is recommended to use LWIP_TCPIP_CORE_LOCKING since this is the way
* with least runtime overhead.
*
* @param fn function to be called from TCPIP thread
* @param apimsg argument to API function
* @param sem semaphore to wait on
* @return ERR_OK if the function was called, another err_t if not
*/
err_t
tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
{
#if LWIP_TCPIP_CORE_LOCKING
LWIP_UNUSED_ARG(sem);
LOCK_TCPIP_CORE();
fn(apimsg);
UNLOCK_TCPIP_CORE();
return ERR_OK;
#else /* LWIP_TCPIP_CORE_LOCKING */
TCPIP_MSG_VAR_DECLARE(msg);
LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
TCPIP_MSG_VAR_ALLOC(msg);
TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API;
TCPIP_MSG_VAR_REF(msg).msg.api_msg.function = fn;
TCPIP_MSG_VAR_REF(msg).msg.api_msg.msg = apimsg;
sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg));
sys_arch_sem_wait(sem, 0);
TCPIP_MSG_VAR_FREE(msg);
return ERR_OK;
#endif /* LWIP_TCPIP_CORE_LOCKING */
}
/**
* Synchronously calls function in TCPIP thread and waits for its completion.
* It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or
* LWIP_NETCONN_SEM_PER_THREAD.
* If not, a semaphore is created and destroyed on every call which is usually
* an expensive/slow operation.
* @param fn Function to call
* @param call Call parameters
* @return Return value from tcpip_api_call_fn
*/
err_t
tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
{
#if LWIP_TCPIP_CORE_LOCKING
err_t err;
LOCK_TCPIP_CORE();
err = fn(call);
UNLOCK_TCPIP_CORE();
return err;
#else /* LWIP_TCPIP_CORE_LOCKING */
TCPIP_MSG_VAR_DECLARE(msg);
#if !LWIP_NETCONN_SEM_PER_THREAD
err_t err = sys_sem_new(&call->sem, 0);
if (err != ERR_OK) {
return err;
}
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
TCPIP_MSG_VAR_ALLOC(msg);
TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API_CALL;
TCPIP_MSG_VAR_REF(msg).msg.api_call.arg = call;
TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn;
#if LWIP_NETCONN_SEM_PER_THREAD
TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET();
#else /* LWIP_NETCONN_SEM_PER_THREAD */
TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem;
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
sys_mbox_post(&tcpip_mbox, &TCPIP_MSG_VAR_REF(msg));
sys_arch_sem_wait(TCPIP_MSG_VAR_REF(msg).msg.api_call.sem, 0);
TCPIP_MSG_VAR_FREE(msg);
#if !LWIP_NETCONN_SEM_PER_THREAD
sys_sem_free(&call->sem);
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
return call->err;
#endif /* LWIP_TCPIP_CORE_LOCKING */
}
/**
* @ingroup lwip_os
* Allocate a structure for a static callback message and initialize it.
* The message has a special type such that lwIP never frees it.
* This is intended to be used to send "static" messages from interrupt context,
* e.g. the message is allocated once and posted several times from an IRQ
* using tcpip_callbackmsg_trycallback().
* Example usage: Trigger execution of an ethernet IRQ DPC routine in lwIP thread context.
*
* @param function the function to call
* @param ctx parameter passed to function
* @return a struct pointer to pass to tcpip_callbackmsg_trycallback().
*
* @see tcpip_callbackmsg_trycallback()
* @see tcpip_callbackmsg_delete()
*/
struct tcpip_callback_msg *
tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
{
struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
if (msg == NULL) {
return NULL;
}
msg->type = TCPIP_MSG_CALLBACK_STATIC;
msg->msg.cb.function = function;
msg->msg.cb.ctx = ctx;
return (struct tcpip_callback_msg *)msg;
}
/**
* @ingroup lwip_os
* Free a callback message allocated by tcpip_callbackmsg_new().
*
* @param msg the message to free
*
* @see tcpip_callbackmsg_new()
*/
void
tcpip_callbackmsg_delete(struct tcpip_callback_msg *msg)
{
memp_free(MEMP_TCPIP_MSG_API, msg);
}
/**
* @ingroup lwip_os
* Try to post a callback-message to the tcpip_thread tcpip_mbox.
*
* @param msg pointer to the message to post
* @return sys_mbox_trypost() return code
*
* @see tcpip_callbackmsg_new()
*/
err_t
tcpip_callbackmsg_trycallback(struct tcpip_callback_msg *msg)
{
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
return sys_mbox_trypost(&tcpip_mbox, msg);
}
/**
* @ingroup lwip_os
* Try to post a callback-message to the tcpip_thread mbox.
* Same as @ref tcpip_callbackmsg_trycallback but calls sys_mbox_trypost_fromisr(),
* mainly to help FreeRTOS, where calls differ between task level and ISR level.
*
* @param msg pointer to the message to post
* @return sys_mbox_trypost_fromisr() return code (without change, so this
* knowledge can be used to e.g. propagate "bool needs_scheduling")
*
* @see tcpip_callbackmsg_new()
*/
err_t
tcpip_callbackmsg_trycallback_fromisr(struct tcpip_callback_msg *msg)
{
LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
return sys_mbox_trypost_fromisr(&tcpip_mbox, msg);
}
/**
* @ingroup lwip_os
* Initialize this module:
* - initialize all sub modules
* - start the tcpip_thread
*
* @param initfunc a function to call when tcpip_thread is running and finished initializing
* @param arg argument to pass to initfunc
*/
void
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{
lwip_init();
tcpip_init_done = initfunc;
tcpip_init_done_arg = arg;
if (sys_mbox_new(&tcpip_mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
}
#if LWIP_TCPIP_CORE_LOCKING
if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
LWIP_ASSERT("failed to create lock_tcpip_core", 0);
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
}
/**
* Simple callback function used with tcpip_callback to free a pbuf
* (pbuf_free has a wrong signature for tcpip_callback)
*
* @param p The pbuf (chain) to be dereferenced.
*/
static void
pbuf_free_int(void *p)
{
struct pbuf *q = (struct pbuf *)p;
pbuf_free(q);
}
/**
* A simple wrapper function that allows you to free a pbuf from interrupt context.
*
* @param p The pbuf (chain) to be dereferenced.
* @return ERR_OK if callback could be enqueued, an err_t if not
*/
err_t
pbuf_free_callback(struct pbuf *p)
{
return tcpip_try_callback(pbuf_free_int, p);
}
/**
* A simple wrapper function that allows you to free heap memory from
* interrupt context.
*
* @param m the heap memory to free
* @return ERR_OK if callback could be enqueued, an err_t if not
*/
err_t
mem_free_callback(void *m)
{
return tcpip_try_callback(mem_free, m);
}
#endif /* !NO_SYS */
+240
View File
@@ -0,0 +1,240 @@
/**
* @file
* Common functions used throughout the stack.
*
* These are reference implementations of the byte swapping functions.
* Again with the aim of being simple, correct and fully portable.
* Byte swapping is the second thing you would want to optimize. You will
* need to port it to your architecture and in your cc.h:
*
* \#define lwip_htons(x) your_htons
* \#define lwip_htonl(x) your_htonl
*
* Note lwip_ntohs() and lwip_ntohl() are merely references to the htonx counterparts.
*
* If you \#define them to htons() and htonl(), you should
* \#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS to prevent lwIP from
* defining htonx/ntohx compatibility macros.
* @defgroup sys_nonstandard Non-standard functions
* @ingroup sys_layer
* lwIP provides default implementations for non-standard functions.
* These can be mapped to OS functions to reduce code footprint if desired.
* All defines related to this section must not be placed in lwipopts.h,
* but in arch/cc.h!
* These options cannot be \#defined in lwipopts.h since they are not options
* of lwIP itself, but options of the lwIP port to your system.
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt
*
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include <string.h>
#if BYTE_ORDER == LITTLE_ENDIAN
#if !defined(lwip_htons)
/**
* Convert an u16_t from host- to network byte order.
*
* @param n u16_t in host byte order
* @return n in network byte order
*/
u16_t
lwip_htons(u16_t n)
{
return PP_HTONS(n);
}
#endif /* lwip_htons */
#if !defined(lwip_htonl)
/**
* Convert an u32_t from host- to network byte order.
*
* @param n u32_t in host byte order
* @return n in network byte order
*/
u32_t
lwip_htonl(u32_t n)
{
return PP_HTONL(n);
}
#endif /* lwip_htonl */
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
#ifndef lwip_strnstr
/**
* @ingroup sys_nonstandard
* lwIP default implementation for strnstr() non-standard function.
* This can be \#defined to strnstr() depending on your platform port.
*/
char *
lwip_strnstr(const char *buffer, const char *token, size_t n)
{
const char *p;
size_t tokenlen = strlen(token);
if (tokenlen == 0) {
return LWIP_CONST_CAST(char *, buffer);
}
for (p = buffer; *p && (p + tokenlen <= buffer + n); p++) {
if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) {
return LWIP_CONST_CAST(char *, p);
}
}
return NULL;
}
#endif
#ifndef lwip_stricmp
/**
* @ingroup sys_nonstandard
* lwIP default implementation for stricmp() non-standard function.
* This can be \#defined to stricmp() depending on your platform port.
*/
int
lwip_stricmp(const char *str1, const char *str2)
{
char c1, c2;
do {
c1 = *str1++;
c2 = *str2++;
if (c1 != c2) {
char c1_upc = c1 | 0x20;
if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
/* characters are not equal an one is in the alphabet range:
downcase both chars and check again */
char c2_upc = c2 | 0x20;
if (c1_upc != c2_upc) {
/* still not equal */
/* don't care for < or > */
return 1;
}
} else {
/* characters are not equal but none is in the alphabet range */
return 1;
}
}
} while (c1 != 0);
return 0;
}
#endif
#ifndef lwip_strnicmp
/**
* @ingroup sys_nonstandard
* lwIP default implementation for strnicmp() non-standard function.
* This can be \#defined to strnicmp() depending on your platform port.
*/
int
lwip_strnicmp(const char *str1, const char *str2, size_t len)
{
char c1, c2;
do {
c1 = *str1++;
c2 = *str2++;
if (c1 != c2) {
char c1_upc = c1 | 0x20;
if ((c1_upc >= 'a') && (c1_upc <= 'z')) {
/* characters are not equal an one is in the alphabet range:
downcase both chars and check again */
char c2_upc = c2 | 0x20;
if (c1_upc != c2_upc) {
/* still not equal */
/* don't care for < or > */
return 1;
}
} else {
/* characters are not equal but none is in the alphabet range */
return 1;
}
}
len--;
} while ((len != 0) && (c1 != 0));
return 0;
}
#endif
#ifndef lwip_itoa
/**
* @ingroup sys_nonstandard
* lwIP default implementation for itoa() non-standard function.
* This can be \#defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform port.
*/
void
lwip_itoa(char *result, size_t bufsize, int number)
{
char *res = result;
char *tmp = result + bufsize - 1;
int n = (number >= 0) ? number : -number;
/* handle invalid bufsize */
if (bufsize < 2) {
if (bufsize == 1) {
*result = 0;
}
return;
}
/* First, add sign */
if (number < 0) {
*res++ = '-';
}
/* Then create the string from the end and stop if buffer full,
and ensure output string is zero terminated */
*tmp = 0;
while ((n != 0) && (tmp > res)) {
char val = (char)('0' + (n % 10));
tmp--;
*tmp = val;
n = n / 10;
}
if (n) {
/* buffer is too small */
*result = 0;
return;
}
if (*tmp == 0) {
/* Nothing added? */
*res++ = '0';
*res++ = 0;
return;
}
/* move from temporary buffer to output buffer (sign is not moved) */
memmove(res, tmp, (size_t)((result + bufsize) - tmp));
}
#endif
@@ -0,0 +1,608 @@
/**
* @file
* Internet checksum functions.\n
*
* These are some reference implementations of the checksum algorithm, with the
* aim of being simple, correct and fully portable. Checksumming is the
* first thing you would want to optimize for your platform. If you create
* your own version, link it in and in your cc.h put:
*
* \#define LWIP_CHKSUM your_checksum_routine
*
* Or you can select from the implementations below by defining
* LWIP_CHKSUM_ALGORITHM to 1, 2 or 3.
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/inet_chksum.h"
#include "lwip/def.h"
#include "lwip/ip_addr.h"
#include <string.h>
#ifndef LWIP_CHKSUM
# define LWIP_CHKSUM lwip_standard_chksum
# ifndef LWIP_CHKSUM_ALGORITHM
# define LWIP_CHKSUM_ALGORITHM 2
# endif
u16_t lwip_standard_chksum(const void *dataptr, int len);
#endif
/* If none set: */
#ifndef LWIP_CHKSUM_ALGORITHM
# define LWIP_CHKSUM_ALGORITHM 0
#endif
#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */
/**
* lwip checksum
*
* @param dataptr points to start of data to be summed at any boundary
* @param len length of data to be summed
* @return host order (!) lwip checksum (non-inverted Internet sum)
*
* @note accumulator size limits summable length to 64k
* @note host endianess is irrelevant (p3 RFC1071)
*/
u16_t
lwip_standard_chksum(const void *dataptr, int len)
{
u32_t acc;
u16_t src;
const u8_t *octetptr;
acc = 0;
/* dataptr may be at odd or even addresses */
octetptr = (const u8_t *)dataptr;
while (len > 1) {
/* declare first octet as most significant
thus assume network order, ignoring host order */
src = (*octetptr) << 8;
octetptr++;
/* declare second octet as least significant */
src |= (*octetptr);
octetptr++;
acc += src;
len -= 2;
}
if (len > 0) {
/* accumulate remaining octet */
src = (*octetptr) << 8;
acc += src;
}
/* add deferred carry bits */
acc = (acc >> 16) + (acc & 0x0000ffffUL);
if ((acc & 0xffff0000UL) != 0) {
acc = (acc >> 16) + (acc & 0x0000ffffUL);
}
/* This maybe a little confusing: reorder sum using lwip_htons()
instead of lwip_ntohs() since it has a little less call overhead.
The caller must invert bits for Internet sum ! */
return lwip_htons((u16_t)acc);
}
#endif
#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */
/*
* Curt McDowell
* Broadcom Corp.
* csm@broadcom.com
*
* IP checksum two bytes at a time with support for
* unaligned buffer.
* Works for len up to and including 0x20000.
* by Curt McDowell, Broadcom Corp. 12/08/2005
*
* @param dataptr points to start of data to be summed at any boundary
* @param len length of data to be summed
* @return host order (!) lwip checksum (non-inverted Internet sum)
*/
u16_t
lwip_standard_chksum(const void *dataptr, int len)
{
const u8_t *pb = (const u8_t *)dataptr;
const u16_t *ps;
u16_t t = 0;
u32_t sum = 0;
int odd = ((mem_ptr_t)pb & 1);
/* Get aligned to u16_t */
if (odd && len > 0) {
((u8_t *)&t)[1] = *pb++;
len--;
}
/* Add the bulk of the data */
ps = (const u16_t *)(const void *)pb;
while (len > 1) {
sum += *ps++;
len -= 2;
}
/* Consume left-over byte, if any */
if (len > 0) {
((u8_t *)&t)[0] = *(const u8_t *)ps;
}
/* Add end bytes */
sum += t;
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
sum = FOLD_U32T(sum);
sum = FOLD_U32T(sum);
/* Swap if alignment was odd */
if (odd) {
sum = SWAP_BYTES_IN_WORD(sum);
}
return (u16_t)sum;
}
#endif
#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */
/**
* An optimized checksum routine. Basically, it uses loop-unrolling on
* the checksum loop, treating the head and tail bytes specially, whereas
* the inner loop acts on 8 bytes at a time.
*
* @arg start of buffer to be checksummed. May be an odd byte address.
* @len number of bytes in the buffer to be checksummed.
* @return host order (!) lwip checksum (non-inverted Internet sum)
*
* by Curt McDowell, Broadcom Corp. December 8th, 2005
*/
u16_t
lwip_standard_chksum(const void *dataptr, int len)
{
const u8_t *pb = (const u8_t *)dataptr;
const u16_t *ps;
u16_t t = 0;
const u32_t *pl;
u32_t sum = 0, tmp;
/* starts at odd byte address? */
int odd = ((mem_ptr_t)pb & 1);
if (odd && len > 0) {
((u8_t *)&t)[1] = *pb++;
len--;
}
ps = (const u16_t *)(const void *)pb;
if (((mem_ptr_t)ps & 3) && len > 1) {
sum += *ps++;
len -= 2;
}
pl = (const u32_t *)(const void *)ps;
while (len > 7) {
tmp = sum + *pl++; /* ping */
if (tmp < sum) {
tmp++; /* add back carry */
}
sum = tmp + *pl++; /* pong */
if (sum < tmp) {
sum++; /* add back carry */
}
len -= 8;
}
/* make room in upper bits */
sum = FOLD_U32T(sum);
ps = (const u16_t *)pl;
/* 16-bit aligned word remaining? */
while (len > 1) {
sum += *ps++;
len -= 2;
}
/* dangling tail byte remaining? */
if (len > 0) { /* include odd byte */
((u8_t *)&t)[0] = *(const u8_t *)ps;
}
sum += t; /* add end bytes */
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
sum = FOLD_U32T(sum);
sum = FOLD_U32T(sum);
if (odd) {
sum = SWAP_BYTES_IN_WORD(sum);
}
return (u16_t)sum;
}
#endif
/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
static u16_t
inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc)
{
struct pbuf *q;
int swapped = 0;
/* iterate through all pbuf in chain */
for (q = p; q != NULL; q = q->next) {
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
(void *)q, (void *)q->next));
acc += LWIP_CHKSUM(q->payload, q->len);
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
/* just executing this next line is probably faster that the if statement needed
to check whether we really need to execute it, and does no harm */
acc = FOLD_U32T(acc);
if (q->len % 2 != 0) {
swapped = !swapped;
acc = SWAP_BYTES_IN_WORD(acc);
}
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
}
if (swapped) {
acc = SWAP_BYTES_IN_WORD(acc);
}
acc += (u32_t)lwip_htons((u16_t)proto);
acc += (u32_t)lwip_htons(proto_len);
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
return (u16_t)~(acc & 0xffffUL);
}
#if LWIP_IPV4
/* inet_chksum_pseudo:
*
* Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
* IP addresses are expected to be in network byte order.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ip address (used for checksum of pseudo header)
* @param dst destination ip address (used for checksum of pseudo header)
* @param proto ip protocol (used for checksum of pseudo header)
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
const ip4_addr_t *src, const ip4_addr_t *dest)
{
u32_t acc;
u32_t addr;
addr = ip4_addr_get_u32(src);
acc = (addr & 0xffffUL);
acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
addr = ip4_addr_get_u32(dest);
acc = (u32_t)(acc + (addr & 0xffffUL));
acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
/* fold down to 16 bits */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
return inet_cksum_pseudo_base(p, proto, proto_len, acc);
}
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
/**
* Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain.
* IPv6 addresses are expected to be in network byte order.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param proto ipv6 protocol/next header (used for checksum of pseudo header)
* @param proto_len length of the ipv6 payload (used for checksum of pseudo header)
* @param src source ipv6 address (used for checksum of pseudo header)
* @param dest destination ipv6 address (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
const ip6_addr_t *src, const ip6_addr_t *dest)
{
u32_t acc = 0;
u32_t addr;
u8_t addr_part;
for (addr_part = 0; addr_part < 4; addr_part++) {
addr = src->addr[addr_part];
acc = (u32_t)(acc + (addr & 0xffffUL));
acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
addr = dest->addr[addr_part];
acc = (u32_t)(acc + (addr & 0xffffUL));
acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
}
/* fold down to 16 bits */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
return inet_cksum_pseudo_base(p, proto, proto_len, acc);
}
#endif /* LWIP_IPV6 */
/* ip_chksum_pseudo:
*
* Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
* IP addresses are expected to be in network byte order.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ip address (used for checksum of pseudo header)
* @param dst destination ip address (used for checksum of pseudo header)
* @param proto ip protocol (used for checksum of pseudo header)
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len,
const ip_addr_t *src, const ip_addr_t *dest)
{
#if LWIP_IPV6
if (IP_IS_V6(dest)) {
return ip6_chksum_pseudo(p, proto, proto_len, ip_2_ip6(src), ip_2_ip6(dest));
}
#endif /* LWIP_IPV6 */
#if LWIP_IPV4 && LWIP_IPV6
else
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#if LWIP_IPV4
{
return inet_chksum_pseudo(p, proto, proto_len, ip_2_ip4(src), ip_2_ip4(dest));
}
#endif /* LWIP_IPV4 */
}
/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */
static u16_t
inet_cksum_pseudo_partial_base(struct pbuf *p, u8_t proto, u16_t proto_len,
u16_t chksum_len, u32_t acc)
{
struct pbuf *q;
int swapped = 0;
u16_t chklen;
/* iterate through all pbuf in chain */
for (q = p; (q != NULL) && (chksum_len > 0); q = q->next) {
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
(void *)q, (void *)q->next));
chklen = q->len;
if (chklen > chksum_len) {
chklen = chksum_len;
}
acc += LWIP_CHKSUM(q->payload, chklen);
chksum_len = (u16_t)(chksum_len - chklen);
LWIP_ASSERT("delete me", chksum_len < 0x7fff);
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
/* fold the upper bit down */
acc = FOLD_U32T(acc);
if (q->len % 2 != 0) {
swapped = !swapped;
acc = SWAP_BYTES_IN_WORD(acc);
}
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
}
if (swapped) {
acc = SWAP_BYTES_IN_WORD(acc);
}
acc += (u32_t)lwip_htons((u16_t)proto);
acc += (u32_t)lwip_htons(proto_len);
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
return (u16_t)~(acc & 0xffffUL);
}
#if LWIP_IPV4
/* inet_chksum_pseudo_partial:
*
* Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
* IP addresses are expected to be in network byte order.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ip address (used for checksum of pseudo header)
* @param dst destination ip address (used for checksum of pseudo header)
* @param proto ip protocol (used for checksum of pseudo header)
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
u16_t chksum_len, const ip4_addr_t *src, const ip4_addr_t *dest)
{
u32_t acc;
u32_t addr;
addr = ip4_addr_get_u32(src);
acc = (addr & 0xffffUL);
acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
addr = ip4_addr_get_u32(dest);
acc = (u32_t)(acc + (addr & 0xffffUL));
acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
/* fold down to 16 bits */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc);
}
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
/**
* Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain.
* IPv6 addresses are expected to be in network byte order. Will only compute for a
* portion of the payload.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param proto ipv6 protocol/next header (used for checksum of pseudo header)
* @param proto_len length of the ipv6 payload (used for checksum of pseudo header)
* @param chksum_len number of payload bytes used to compute chksum
* @param src source ipv6 address (used for checksum of pseudo header)
* @param dest destination ipv6 address (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
u16_t chksum_len, const ip6_addr_t *src, const ip6_addr_t *dest)
{
u32_t acc = 0;
u32_t addr;
u8_t addr_part;
for (addr_part = 0; addr_part < 4; addr_part++) {
addr = src->addr[addr_part];
acc = (u32_t)(acc + (addr & 0xffffUL));
acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
addr = dest->addr[addr_part];
acc = (u32_t)(acc + (addr & 0xffffUL));
acc = (u32_t)(acc + ((addr >> 16) & 0xffffUL));
}
/* fold down to 16 bits */
acc = FOLD_U32T(acc);
acc = FOLD_U32T(acc);
return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc);
}
#endif /* LWIP_IPV6 */
/* ip_chksum_pseudo_partial:
*
* Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain.
*
* @param p chain of pbufs over that a checksum should be calculated (ip data part)
* @param src source ip address (used for checksum of pseudo header)
* @param dst destination ip address (used for checksum of pseudo header)
* @param proto ip protocol (used for checksum of pseudo header)
* @param proto_len length of the ip data part (used for checksum of pseudo header)
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
ip_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len,
u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest)
{
#if LWIP_IPV6
if (IP_IS_V6(dest)) {
return ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip6(src), ip_2_ip6(dest));
}
#endif /* LWIP_IPV6 */
#if LWIP_IPV4 && LWIP_IPV6
else
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#if LWIP_IPV4
{
return inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip4(src), ip_2_ip4(dest));
}
#endif /* LWIP_IPV4 */
}
/* inet_chksum:
*
* Calculates the Internet checksum over a portion of memory. Used primarily for IP
* and ICMP.
*
* @param dataptr start of the buffer to calculate the checksum (no alignment needed)
* @param len length of the buffer to calculate the checksum
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
inet_chksum(const void *dataptr, u16_t len)
{
return (u16_t)~(unsigned int)LWIP_CHKSUM(dataptr, len);
}
/**
* Calculate a checksum over a chain of pbufs (without pseudo-header, much like
* inet_chksum only pbufs are used).
*
* @param p pbuf chain over that the checksum should be calculated
* @return checksum (as u16_t) to be saved directly in the protocol header
*/
u16_t
inet_chksum_pbuf(struct pbuf *p)
{
u32_t acc;
struct pbuf *q;
int swapped = 0;
acc = 0;
for (q = p; q != NULL; q = q->next) {
acc += LWIP_CHKSUM(q->payload, q->len);
acc = FOLD_U32T(acc);
if (q->len % 2 != 0) {
swapped = !swapped;
acc = SWAP_BYTES_IN_WORD(acc);
}
}
if (swapped) {
acc = SWAP_BYTES_IN_WORD(acc);
}
return (u16_t)~(acc & 0xffffUL);
}
/* These are some implementations for LWIP_CHKSUM_COPY, which copies data
* like MEMCPY but generates a checksum at the same time. Since this is a
* performance-sensitive function, you might want to create your own version
* in assembly targeted at your hardware by defining it in lwipopts.h:
* #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len)
*/
#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */
/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM.
* For architectures with big caches, data might still be in cache when
* generating the checksum after copying.
*/
u16_t
lwip_chksum_copy(void *dst, const void *src, u16_t len)
{
MEMCPY(dst, src, len);
return LWIP_CHKSUM(dst, len);
}
#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */
+380
View File
@@ -0,0 +1,380 @@
/**
* @file
* Modules initialization
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*/
#include "lwip/opt.h"
#include "lwip/init.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/pbuf.h"
#include "lwip/netif.h"
#include "lwip/sockets.h"
#include "lwip/ip.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/igmp.h"
#include "lwip/dns.h"
#include "lwip/timeouts.h"
#include "lwip/etharp.h"
#include "lwip/ip6.h"
#include "lwip/nd6.h"
#include "lwip/mld6.h"
#include "lwip/api.h"
#include "netif/ppp/ppp_opts.h"
#include "netif/ppp/ppp_impl.h"
#ifndef LWIP_SKIP_PACKING_CHECK
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct packed_struct_test {
PACK_STRUCT_FLD_8(u8_t dummy1);
PACK_STRUCT_FIELD(u32_t dummy2);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define PACKED_STRUCT_TEST_EXPECTED_SIZE 5
#endif
/* Compile-time sanity checks for configuration errors.
* These can be done independently of LWIP_DEBUG, without penalty.
*/
#ifndef BYTE_ORDER
#error "BYTE_ORDER is not defined, you have to define it in your cc.h"
#endif
#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV)
#error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_UDPLITE)
#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_DHCP)
#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && !LWIP_RAW && LWIP_MULTICAST_TX_OPTIONS)
#error "If you want to use LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 and/or LWIP_RAW=1 in your lwipopts.h"
#endif
#if (!LWIP_UDP && LWIP_DNS)
#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h"
#endif
#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */
#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0))
#error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h"
#endif
#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0))
#error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0))
#error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0))
#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
#endif
#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
#endif
#if (LWIP_IGMP && !LWIP_MULTICAST_TX_OPTIONS)
#error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h"
#endif
#if (LWIP_IGMP && !LWIP_IPV4)
#error "IGMP needs LWIP_IPV4 enabled in your lwipopts.h"
#endif
#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0))
#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h"
#endif
/* There must be sufficient timeouts, taking into account requirements of the subsystems. */
#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < LWIP_NUM_SYS_TIMEOUT_INTERNAL)
#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts"
#endif
#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS))
#error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!"
#endif
#endif /* !MEMP_MEM_MALLOC */
#if LWIP_WND_SCALE
#if (LWIP_TCP && (TCP_WND > 0xffffffff))
#error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h"
#endif
#if (LWIP_TCP && (TCP_RCV_SCALE > 14))
#error "The maximum valid window scale value is 14!"
#endif
#if (LWIP_TCP && (TCP_WND > (0xFFFFU << TCP_RCV_SCALE)))
#error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!"
#endif
#if (LWIP_TCP && ((TCP_WND >> TCP_RCV_SCALE) == 0))
#error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!"
#endif
#else /* LWIP_WND_SCALE */
#if (LWIP_TCP && (TCP_WND > 0xffff))
#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)"
#endif
#endif /* LWIP_WND_SCALE */
#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
#endif
#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2))
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
#endif
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
#endif
#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)))
#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t"
#endif
#if (LWIP_TCP && LWIP_TCP_SACK_OUT && !TCP_QUEUE_OOSEQ)
#error "To use LWIP_TCP_SACK_OUT, TCP_QUEUE_OOSEQ needs to be enabled"
#endif
#if (LWIP_TCP && LWIP_TCP_SACK_OUT && (LWIP_TCP_MAX_SACK_NUM < 1))
#error "LWIP_TCP_MAX_SACK_NUM must be greater than 0"
#endif
#if (LWIP_NETIF_API && (NO_SYS==1))
#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1))
#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if (LWIP_PPP_API && (NO_SYS==1))
#error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h"
#endif
#if (LWIP_PPP_API && (PPP_SUPPORT==0))
#error "If you want to use PPP API, you have to enable PPP_SUPPORT in your lwipopts.h"
#endif
#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP)
#error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h"
#endif
#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK)
#error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h"
#endif
#if (!LWIP_ARP && LWIP_AUTOIP)
#error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h"
#endif
#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API)))
#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h"
#endif
#if (LWIP_ALTCP && LWIP_EVENT_API)
#error "The application layered tcp API does not work with LWIP_EVENT_API"
#endif
#if (MEM_LIBC_MALLOC && MEM_USE_POOLS)
#error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h"
#endif
#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS)
#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h"
#endif
#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT)
#error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf"
#endif
#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT)))
#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST"
#endif
#if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT && !PPPOL2TP_SUPPORT
#error "PPP_SUPPORT needs at least one of PPPOS_SUPPORT, PPPOE_SUPPORT or PPPOL2TP_SUPPORT turned on"
#endif
#if PPP_SUPPORT && !PPP_IPV4_SUPPORT && !PPP_IPV6_SUPPORT
#error "PPP_SUPPORT needs PPP_IPV4_SUPPORT and/or PPP_IPV6_SUPPORT turned on"
#endif
#if PPP_SUPPORT && PPP_IPV4_SUPPORT && !LWIP_IPV4
#error "PPP_IPV4_SUPPORT needs LWIP_IPV4 turned on"
#endif
#if PPP_SUPPORT && PPP_IPV6_SUPPORT && !LWIP_IPV6
#error "PPP_IPV6_SUPPORT needs LWIP_IPV6 turned on"
#endif
#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT)
#error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT"
#endif
#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING
#error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too"
#endif
#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE
#error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets"
#endif
#if LWIP_NETCONN && LWIP_TCP
#if NETCONN_COPY != TCP_WRITE_FLAG_COPY
#error "NETCONN_COPY != TCP_WRITE_FLAG_COPY"
#endif
#if NETCONN_MORE != TCP_WRITE_FLAG_MORE
#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
#endif
#endif /* LWIP_NETCONN && LWIP_TCP */
#if LWIP_SOCKET
#endif /* LWIP_SOCKET */
/* Compile-time checks for deprecated options.
*/
#ifdef MEMP_NUM_TCPIP_MSG
#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef TCP_REXMIT_DEBUG
#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef RAW_STATS
#error "RAW_STATS option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef ETHARP_QUEUE_FIRST
#error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h."
#endif
#ifdef ETHARP_ALWAYS_INSERT
#error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h."
#endif
#if !NO_SYS && LWIP_TCPIP_CORE_LOCKING && LWIP_COMPAT_MUTEX && !defined(LWIP_COMPAT_MUTEX_ALLOWED)
#error "LWIP_COMPAT_MUTEX cannot prevent priority inversion. It is recommended to implement priority-aware mutexes. (Define LWIP_COMPAT_MUTEX_ALLOWED to disable this error.)"
#endif
#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS
#define LWIP_DISABLE_TCP_SANITY_CHECKS 0
#endif
#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS
#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0
#endif
/* MEMP sanity checks */
#if MEMP_MEM_MALLOC
#if !LWIP_DISABLE_MEMP_SANITY_CHECKS
#if LWIP_NETCONN || LWIP_SOCKET
#if !MEMP_NUM_NETCONN && LWIP_SOCKET
#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!"
#endif
#else /* MEMP_MEM_MALLOC */
#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB)
#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error."
#endif
#endif /* LWIP_NETCONN || LWIP_SOCKET */
#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */
#if MEM_USE_POOLS
#error "MEMP_MEM_MALLOC and MEM_USE_POOLS cannot be enabled at the same time"
#endif
#ifdef LWIP_HOOK_MEMP_AVAILABLE
#error "LWIP_HOOK_MEMP_AVAILABLE doesn't make sense with MEMP_MEM_MALLOC"
#endif
#endif /* MEMP_MEM_MALLOC */
/* TCP sanity checks */
#if !LWIP_DISABLE_TCP_SANITY_CHECKS
#if LWIP_TCP
#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN)
#error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_SND_BUF < (2 * TCP_MSS)
#error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS))
#error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_SNDLOWAT >= TCP_SND_BUF
#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS))
#error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!"
#endif
#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN
#error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))
#error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN))))
#error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#if TCP_WND < TCP_MSS
#error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error."
#endif
#endif /* LWIP_TCP */
#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */
/**
* @ingroup lwip_nosys
* Initialize all modules.
* Use this in NO_SYS mode. Use tcpip_init() otherwise.
*/
void
lwip_init(void)
{
#ifndef LWIP_SKIP_CONST_CHECK
int a = 0;
LWIP_UNUSED_ARG(a);
LWIP_ASSERT("LWIP_CONST_CAST not implemented correctly. Check your lwIP port.", LWIP_CONST_CAST(void *, &a) == &a);
#endif
#ifndef LWIP_SKIP_PACKING_CHECK
LWIP_ASSERT("Struct packing not implemented correctly. Check your lwIP port.", sizeof(struct packed_struct_test) == PACKED_STRUCT_TEST_EXPECTED_SIZE);
#endif
/* Modules initialization */
stats_init();
#if !NO_SYS
sys_init();
#endif /* !NO_SYS */
mem_init();
memp_init();
pbuf_init();
netif_init();
#if LWIP_IPV4
ip_init();
#if LWIP_ARP
etharp_init();
#endif /* LWIP_ARP */
#endif /* LWIP_IPV4 */
#if LWIP_RAW
raw_init();
#endif /* LWIP_RAW */
#if LWIP_UDP
udp_init();
#endif /* LWIP_UDP */
#if LWIP_TCP
tcp_init();
#endif /* LWIP_TCP */
#if LWIP_IGMP
igmp_init();
#endif /* LWIP_IGMP */
#if LWIP_DNS
dns_init();
#endif /* LWIP_DNS */
#if PPP_SUPPORT
ppp_init();
#endif
#if LWIP_TIMERS
sys_timeouts_init();
#endif /* LWIP_TIMERS */
}
+167
View File
@@ -0,0 +1,167 @@
/**
* @file
* Common IPv4 and IPv6 code
*
* @defgroup ip IP
* @ingroup callbackstyle_api
*
* @defgroup ip4 IPv4
* @ingroup ip
*
* @defgroup ip6 IPv6
* @ingroup ip
*
* @defgroup ipaddr IP address handling
* @ingroup infrastructure
*
* @defgroup ip4addr IPv4 only
* @ingroup ipaddr
*
* @defgroup ip6addr IPv6 only
* @ingroup ipaddr
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_IPV4 || LWIP_IPV6
#include "lwip/ip_addr.h"
#include "lwip/ip.h"
/** Global data for both IPv4 and IPv6 */
struct ip_globals ip_data;
#if LWIP_IPV4 && LWIP_IPV6
const ip_addr_t ip_addr_any_type = IPADDR_ANY_TYPE_INIT;
/**
* @ingroup ipaddr
* Convert numeric IP address (both versions) into ASCII representation.
* returns ptr to static buffer; not reentrant!
*
* @param addr ip address in network order to convert
* @return pointer to a global static (!) buffer that holds the ASCII
* representation of addr
*/
char *ipaddr_ntoa(const ip_addr_t *addr)
{
if (addr == NULL) {
return NULL;
}
if (IP_IS_V6(addr)) {
return ip6addr_ntoa(ip_2_ip6(addr));
} else {
return ip4addr_ntoa(ip_2_ip4(addr));
}
}
/**
* @ingroup ipaddr
* Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
*
* @param addr ip address in network order to convert
* @param buf target buffer where the string is stored
* @param buflen length of buf
* @return either pointer to buf which now holds the ASCII
* representation of addr or NULL if buf was too small
*/
char *ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen)
{
if (addr == NULL) {
return NULL;
}
if (IP_IS_V6(addr)) {
return ip6addr_ntoa_r(ip_2_ip6(addr), buf, buflen);
} else {
return ip4addr_ntoa_r(ip_2_ip4(addr), buf, buflen);
}
}
/**
* @ingroup ipaddr
* Convert IP address string (both versions) to numeric.
* The version is auto-detected from the string.
*
* @param cp IP address string to convert
* @param addr conversion result is stored here
* @return 1 on success, 0 on error
*/
int
ipaddr_aton(const char *cp, ip_addr_t *addr)
{
if (cp != NULL) {
const char *c;
for (c = cp; *c != 0; c++) {
if (*c == ':') {
/* contains a colon: IPv6 address */
if (addr) {
IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V6);
}
return ip6addr_aton(cp, ip_2_ip6(addr));
} else if (*c == '.') {
/* contains a dot: IPv4 address */
break;
}
}
/* call ip4addr_aton as fallback or if IPv4 was found */
if (addr) {
IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V4);
}
return ip4addr_aton(cp, ip_2_ip4(addr));
}
return 0;
}
/**
* @ingroup lwip_nosys
* If both IP versions are enabled, this function can dispatch packets to the correct one.
* Don't call directly, pass to netif_add() and call netif->input().
*/
err_t
ip_input(struct pbuf *p, struct netif *inp)
{
if (p != NULL) {
if (IP_HDR_GET_VERSION(p->payload) == 6) {
return ip6_input(p, inp);
}
return ip4_input(p, inp);
}
return ERR_VAL;
}
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#endif /* LWIP_IPV4 || LWIP_IPV6 */
@@ -0,0 +1,527 @@
/**
* @file
* AutoIP Automatic LinkLocal IP Configuration
*
* This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
* with RFC 3927.
*
* @defgroup autoip AUTOIP
* @ingroup ip4
* AUTOIP related functions
* USAGE:
*
* define @ref LWIP_AUTOIP 1 in your lwipopts.h
* Options:
* AUTOIP_TMR_INTERVAL msecs,
* I recommend a value of 100. The value must divide 1000 with a remainder almost 0.
* Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 ....
*
* Without DHCP:
* - Call autoip_start() after netif_add().
*
* With DHCP:
* - define @ref LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h.
* - Configure your DHCP Client.
*
* @see netifapi_autoip
*/
/*
*
* Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* Author: Dominik Spies <kontakt@dspies.de>
*/
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
#include "lwip/mem.h"
/* #include "lwip/udp.h" */
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/autoip.h"
#include "lwip/etharp.h"
#include "lwip/prot/autoip.h"
#include <string.h>
/** Pseudo random macro based on netif informations.
* You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */
#ifndef LWIP_AUTOIP_RAND
#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \
((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \
((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \
((u32_t)((netif->hwaddr[4]) & 0xff))) + \
(netif_autoip_data(netif)? netif_autoip_data(netif)->tried_llipaddr : 0))
#endif /* LWIP_AUTOIP_RAND */
/**
* Macro that generates the initial IP address to be tried by AUTOIP.
* If you want to override this, define it to something else in lwipopts.h.
*/
#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR
#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \
lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \
((u32_t)((u8_t)(netif->hwaddr[5]))) << 8)))
#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */
/* static functions */
static err_t autoip_arp_announce(struct netif *netif);
static void autoip_start_probing(struct netif *netif);
/**
* @ingroup autoip
* Set a statically allocated struct autoip to work with.
* Using this prevents autoip_start to allocate it using mem_malloc.
*
* @param netif the netif for which to set the struct autoip
* @param autoip (uninitialised) autoip struct allocated by the application
*/
void
autoip_set_struct(struct netif *netif, struct autoip *autoip)
{
LWIP_ASSERT_CORE_LOCKED();
LWIP_ASSERT("netif != NULL", netif != NULL);
LWIP_ASSERT("autoip != NULL", autoip != NULL);
LWIP_ASSERT("netif already has a struct autoip set",
netif_autoip_data(netif) == NULL);
/* clear data structure */
memset(autoip, 0, sizeof(struct autoip));
/* autoip->state = AUTOIP_STATE_OFF; */
netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
}
/** Restart AutoIP client and check the next address (conflict detected)
*
* @param netif The netif under AutoIP control
*/
static void
autoip_restart(struct netif *netif)
{
struct autoip *autoip = netif_autoip_data(netif);
autoip->tried_llipaddr++;
autoip_start(netif);
}
/**
* Handle a IP address conflict after an ARP conflict detection
*/
static void
autoip_handle_arp_conflict(struct netif *netif)
{
struct autoip *autoip = netif_autoip_data(netif);
/* RFC3927, 2.5 "Conflict Detection and Defense" allows two options where
a) means retreat on the first conflict and
b) allows to keep an already configured address when having only one
conflict in 10 seconds
We use option b) since it helps to improve the chance that one of the two
conflicting hosts may be able to retain its address. */
if (autoip->lastconflict > 0) {
/* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n"));
/* Active TCP sessions are aborted when removing the ip addresss */
autoip_restart(netif);
} else {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n"));
autoip_arp_announce(netif);
autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
}
/**
* Create an IP-Address out of range 169.254.1.0 to 169.254.254.255
*
* @param netif network interface on which create the IP-Address
* @param ipaddr ip address to initialize
*/
static void
autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr)
{
struct autoip *autoip = netif_autoip_data(netif);
/* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255
* compliant to RFC 3927 Section 2.1
* We have 254 * 256 possibilities */
u32_t addr = lwip_ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif));
addr += autoip->tried_llipaddr;
addr = AUTOIP_NET | (addr & 0xffff);
/* Now, 169.254.0.0 <= addr <= 169.254.255.255 */
if (addr < AUTOIP_RANGE_START) {
addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
}
if (addr > AUTOIP_RANGE_END) {
addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1;
}
LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) &&
(addr <= AUTOIP_RANGE_END));
ip4_addr_set_u32(ipaddr, lwip_htonl(addr));
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
(u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr),
ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));
}
/**
* Sends an ARP probe from a network interface
*
* @param netif network interface used to send the probe
*/
static err_t
autoip_arp_probe(struct netif *netif)
{
struct autoip *autoip = netif_autoip_data(netif);
/* this works because netif->ip_addr is ANY */
return etharp_request(netif, &autoip->llipaddr);
}
/**
* Sends an ARP announce from a network interface
*
* @param netif network interface used to send the announce
*/
static err_t
autoip_arp_announce(struct netif *netif)
{
return etharp_gratuitous(netif);
}
/**
* Configure interface for use with current LL IP-Address
*
* @param netif network interface to configure with current LL IP-Address
*/
static err_t
autoip_bind(struct netif *netif)
{
struct autoip *autoip = netif_autoip_data(netif);
ip4_addr_t sn_mask, gw_addr;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
(void *)netif, netif->name[0], netif->name[1], (u16_t)netif->num,
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
IP4_ADDR(&sn_mask, 255, 255, 0, 0);
IP4_ADDR(&gw_addr, 0, 0, 0, 0);
netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr);
/* interface is used by routing now that an address is set */
return ERR_OK;
}
/**
* @ingroup autoip
* Start AutoIP client
*
* @param netif network interface on which start the AutoIP client
*/
err_t
autoip_start(struct netif *netif)
{
struct autoip *autoip = netif_autoip_data(netif);
err_t result = ERR_OK;
LWIP_ASSERT_CORE_LOCKED();
LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;);
/* Set IP-Address, Netmask and Gateway to 0 to make sure that
* ARP Packets are formed correctly
*/
netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_start(netif=%p) %c%c%"U16_F"\n", (void *)netif, netif->name[0],
netif->name[1], (u16_t)netif->num));
if (autoip == NULL) {
/* no AutoIP client attached yet? */
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_start(): starting new AUTOIP client\n"));
autoip = (struct autoip *)mem_calloc(1, sizeof(struct autoip));
if (autoip == NULL) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_start(): could not allocate autoip\n"));
return ERR_MEM;
}
/* store this AutoIP client in the netif */
netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip"));
} else {
autoip->state = AUTOIP_STATE_OFF;
autoip->ttw = 0;
autoip->sent_num = 0;
ip4_addr_set_zero(&autoip->llipaddr);
autoip->lastconflict = 0;
}
autoip_create_addr(netif, &(autoip->llipaddr));
autoip_start_probing(netif);
return result;
}
static void
autoip_start_probing(struct netif *netif)
{
struct autoip *autoip = netif_autoip_data(netif);
autoip->state = AUTOIP_STATE_PROBING;
autoip->sent_num = 0;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
/* time to wait to first probe, this is randomly
* chosen out of 0 to PROBE_WAIT seconds.
* compliant to RFC 3927 Section 2.2.1
*/
autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND));
/*
* if we tried more then MAX_CONFLICTS we must limit our rate for
* acquiring and probing address
* compliant to RFC 3927 Section 2.2.1
*/
if (autoip->tried_llipaddr > MAX_CONFLICTS) {
autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND;
}
}
/**
* Handle a possible change in the network configuration.
*
* If there is an AutoIP address configured, take the interface down
* and begin probing with the same address.
*/
void
autoip_network_changed(struct netif *netif)
{
struct autoip *autoip = netif_autoip_data(netif);
if (autoip && (autoip->state != AUTOIP_STATE_OFF)) {
autoip_start_probing(netif);
}
}
/**
* @ingroup autoip
* Stop AutoIP client
*
* @param netif network interface on which stop the AutoIP client
*/
err_t
autoip_stop(struct netif *netif)
{
struct autoip *autoip = netif_autoip_data(netif);
LWIP_ASSERT_CORE_LOCKED();
if (autoip != NULL) {
autoip->state = AUTOIP_STATE_OFF;
if (ip4_addr_islinklocal(netif_ip4_addr(netif))) {
netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
}
}
return ERR_OK;
}
/**
* Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
*/
void
autoip_tmr(void)
{
struct netif *netif;
/* loop through netif's */
NETIF_FOREACH(netif) {
struct autoip *autoip = netif_autoip_data(netif);
/* only act on AutoIP configured interfaces */
if (autoip != NULL) {
if (autoip->lastconflict > 0) {
autoip->lastconflict--;
}
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE,
("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n",
(u16_t)(autoip->state), autoip->ttw));
if (autoip->ttw > 0) {
autoip->ttw--;
}
switch (autoip->state) {
case AUTOIP_STATE_PROBING:
if (autoip->ttw == 0) {
if (autoip->sent_num >= PROBE_NUM) {
/* Switch to ANNOUNCING: now we can bind to an IP address and use it */
autoip->state = AUTOIP_STATE_ANNOUNCING;
autoip_bind(netif);
/* autoip_bind() calls netif_set_addr(): this triggers a gratuitous ARP
which counts as an announcement */
autoip->sent_num = 1;
autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
} else {
autoip_arp_probe(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n"));
autoip->sent_num++;
if (autoip->sent_num == PROBE_NUM) {
/* calculate time to wait to for announce */
autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
} else {
/* calculate time to wait to next probe */
autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) %
((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) +
PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
}
}
}
break;
case AUTOIP_STATE_ANNOUNCING:
if (autoip->ttw == 0) {
autoip_arp_announce(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() ANNOUNCING Sent Announce\n"));
autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
autoip->sent_num++;
if (autoip->sent_num >= ANNOUNCE_NUM) {
autoip->state = AUTOIP_STATE_BOUND;
autoip->sent_num = 0;
autoip->ttw = 0;
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE,
("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr),
ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr)));
}
}
break;
default:
/* nothing to do in other states */
break;
}
}
}
}
/**
* Handles every incoming ARP Packet, called by etharp_input().
*
* @param netif network interface to use for autoip processing
* @param hdr Incoming ARP packet
*/
void
autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
{
struct autoip *autoip = netif_autoip_data(netif);
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n"));
if ((autoip != NULL) && (autoip->state != AUTOIP_STATE_OFF)) {
/* when ip.src == llipaddr && hw.src != netif->hwaddr
*
* when probing ip.dst == llipaddr && hw.src != netif->hwaddr
* we have a conflict and must solve it
*/
ip4_addr_t sipaddr, dipaddr;
struct eth_addr netifaddr;
SMEMCPY(netifaddr.addr, netif->hwaddr, ETH_HWADDR_LEN);
/* Copy struct ip4_addr_wordaligned to aligned ip4_addr, to support compilers without
* structure packing (not using structure copy which breaks strict-aliasing rules).
*/
IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&sipaddr, &hdr->sipaddr);
IPADDR_WORDALIGNED_COPY_TO_IP4_ADDR_T(&dipaddr, &hdr->dipaddr);
if (autoip->state == AUTOIP_STATE_PROBING) {
/* RFC 3927 Section 2.2.1:
* from beginning to after ANNOUNCE_WAIT
* seconds we have a conflict if
* ip.src == llipaddr OR
* ip.dst == llipaddr && hw.src != own hwaddr
*/
if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) ||
(ip4_addr_isany_val(sipaddr) &&
ip4_addr_cmp(&dipaddr, &autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr))) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Probe Conflict detected\n"));
autoip_restart(netif);
}
} else {
/* RFC 3927 Section 2.5:
* in any state we have a conflict if
* ip.src == llipaddr && hw.src != own hwaddr
*/
if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) &&
!eth_addr_cmp(&netifaddr, &hdr->shwaddr)) {
LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING,
("autoip_arp_reply(): Conflicting ARP-Packet detected\n"));
autoip_handle_arp_conflict(netif);
}
}
}
}
/** check if AutoIP supplied netif->ip_addr
*
* @param netif the netif to check
* @return 1 if AutoIP supplied netif->ip_addr (state BOUND or ANNOUNCING),
* 0 otherwise
*/
u8_t
autoip_supplied_address(const struct netif *netif)
{
if ((netif != NULL) && (netif_autoip_data(netif) != NULL)) {
struct autoip *autoip = netif_autoip_data(netif);
return (autoip->state == AUTOIP_STATE_BOUND) || (autoip->state == AUTOIP_STATE_ANNOUNCING);
}
return 0;
}
u8_t
autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr)
{
struct autoip *autoip = netif_autoip_data(netif);
return (autoip != NULL) && ip4_addr_cmp(addr, &(autoip->llipaddr));
}
#endif /* LWIP_IPV4 && LWIP_AUTOIP */
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,404 @@
/**
* @file
* ICMP - Internet Control Message Protocol
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/* Some ICMP messages should be passed to the transport protocols. This
is not implemented. */
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/icmp.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#include "lwip/def.h"
#include "lwip/stats.h"
#include <string.h>
#ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME
#endif
/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be
* used to modify and send a response packet (and to 1 if this is not the case,
* e.g. when link header is stripped off when receiving) */
#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
/* The amount of data from the original packet to return in a dest-unreachable */
#define ICMP_DEST_UNREACH_DATASIZE 8
static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
/**
* Processes ICMP input packets, called from ip_input().
*
* Currently only processes icmp echo requests and sends
* out the echo response.
*
* @param p the icmp echo request packet, p->payload pointing to the icmp header
* @param inp the netif on which this packet was received
*/
void
icmp_input(struct pbuf *p, struct netif *inp)
{
u8_t type;
#ifdef LWIP_DEBUG
u8_t code;
#endif /* LWIP_DEBUG */
struct icmp_echo_hdr *iecho;
const struct ip_hdr *iphdr_in;
u16_t hlen;
const ip4_addr_t *src;
ICMP_STATS_INC(icmp.recv);
MIB2_STATS_INC(mib2.icmpinmsgs);
iphdr_in = ip4_current_header();
hlen = IPH_HL_BYTES(iphdr_in);
if (hlen < IP_HLEN) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%"S16_F" bytes) received\n", hlen));
goto lenerr;
}
if (p->len < sizeof(u16_t) * 2) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len));
goto lenerr;
}
type = *((u8_t *)p->payload);
#ifdef LWIP_DEBUG
code = *(((u8_t *)p->payload) + 1);
/* if debug is enabled but debug statement below is somehow disabled: */
LWIP_UNUSED_ARG(code);
#endif /* LWIP_DEBUG */
switch (type) {
case ICMP_ER:
/* This is OK, echo reply might have been parsed by a raw PCB
(as obviously, an echo request has been sent, too). */
MIB2_STATS_INC(mib2.icmpinechoreps);
break;
case ICMP_ECHO:
MIB2_STATS_INC(mib2.icmpinechos);
src = ip4_current_dest_addr();
/* multicast destination address? */
if (ip4_addr_ismulticast(ip4_current_dest_addr())) {
#if LWIP_MULTICAST_PING
/* For multicast, use address of receiving interface as source address */
src = netif_ip4_addr(inp);
#else /* LWIP_MULTICAST_PING */
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n"));
goto icmperr;
#endif /* LWIP_MULTICAST_PING */
}
/* broadcast destination address? */
if (ip4_addr_isbroadcast(ip4_current_dest_addr(), ip_current_netif())) {
#if LWIP_BROADCAST_PING
/* For broadcast, use address of receiving interface as source address */
src = netif_ip4_addr(inp);
#else /* LWIP_BROADCAST_PING */
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n"));
goto icmperr;
#endif /* LWIP_BROADCAST_PING */
}
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
goto lenerr;
}
#if CHECKSUM_CHECK_ICMP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) {
if (inet_chksum_pbuf(p) != 0) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n"));
pbuf_free(p);
ICMP_STATS_INC(icmp.chkerr);
MIB2_STATS_INC(mib2.icmpinerrors);
return;
}
}
#endif
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
if (pbuf_add_header(p, hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN)) {
/* p is not big enough to contain link headers
* allocate a new one and copy p into it
*/
struct pbuf *r;
u16_t alloc_len = (u16_t)(p->tot_len + hlen);
if (alloc_len < p->tot_len) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed (tot_len overflow)\n"));
goto icmperr;
}
/* allocate new packet buffer with space for link headers */
r = pbuf_alloc(PBUF_LINK, alloc_len, PBUF_RAM);
if (r == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n"));
goto icmperr;
}
if (r->len < hlen + sizeof(struct icmp_echo_hdr)) {
LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("first pbuf cannot hold the ICMP header"));
pbuf_free(r);
goto icmperr;
}
/* copy the ip header */
MEMCPY(r->payload, iphdr_in, hlen);
/* switch r->payload back to icmp header (cannot fail) */
if (pbuf_remove_header(r, hlen)) {
LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0);
pbuf_free(r);
goto icmperr;
}
/* copy the rest of the packet without ip header */
if (pbuf_copy(r, p) != ERR_OK) {
LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("icmp_input: copying to new pbuf failed"));
pbuf_free(r);
goto icmperr;
}
/* free the original p */
pbuf_free(p);
/* we now have an identical copy of p that has room for link headers */
p = r;
} else {
/* restore p->payload to point to icmp header (cannot fail) */
if (pbuf_remove_header(p, hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN)) {
LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0);
goto icmperr;
}
}
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
/* At this point, all checks are OK. */
/* We generate an answer by switching the dest and src ip addresses,
* setting the icmp type to ECHO_RESPONSE and updating the checksum. */
iecho = (struct icmp_echo_hdr *)p->payload;
if (pbuf_add_header(p, hlen)) {
LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Can't move over header in packet"));
} else {
err_t ret;
struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
ip4_addr_copy(iphdr->src, *src);
ip4_addr_copy(iphdr->dest, *ip4_current_src_addr());
ICMPH_TYPE_SET(iecho, ICMP_ER);
#if CHECKSUM_GEN_ICMP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) {
/* adjust the checksum */
if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS((u16_t)(ICMP_ECHO << 8)) + 1);
} else {
iecho->chksum = (u16_t)(iecho->chksum + PP_HTONS(ICMP_ECHO << 8));
}
}
#if LWIP_CHECKSUM_CTRL_PER_NETIF
else {
iecho->chksum = 0;
}
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
#else /* CHECKSUM_GEN_ICMP */
iecho->chksum = 0;
#endif /* CHECKSUM_GEN_ICMP */
/* Set the correct TTL and recalculate the header checksum. */
IPH_TTL_SET(iphdr, ICMP_TTL);
IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen));
}
#endif /* CHECKSUM_GEN_IP */
ICMP_STATS_INC(icmp.xmit);
/* increase number of messages attempted to send */
MIB2_STATS_INC(mib2.icmpoutmsgs);
/* increase number of echo replies attempted to send */
MIB2_STATS_INC(mib2.icmpoutechoreps);
/* send an ICMP packet */
ret = ip4_output_if(p, src, LWIP_IP_HDRINCL,
ICMP_TTL, 0, IP_PROTO_ICMP, inp);
if (ret != ERR_OK) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret)));
}
}
break;
default:
if (type == ICMP_DUR) {
MIB2_STATS_INC(mib2.icmpindestunreachs);
} else if (type == ICMP_TE) {
MIB2_STATS_INC(mib2.icmpintimeexcds);
} else if (type == ICMP_PP) {
MIB2_STATS_INC(mib2.icmpinparmprobs);
} else if (type == ICMP_SQ) {
MIB2_STATS_INC(mib2.icmpinsrcquenchs);
} else if (type == ICMP_RD) {
MIB2_STATS_INC(mib2.icmpinredirects);
} else if (type == ICMP_TS) {
MIB2_STATS_INC(mib2.icmpintimestamps);
} else if (type == ICMP_TSR) {
MIB2_STATS_INC(mib2.icmpintimestampreps);
} else if (type == ICMP_AM) {
MIB2_STATS_INC(mib2.icmpinaddrmasks);
} else if (type == ICMP_AMR) {
MIB2_STATS_INC(mib2.icmpinaddrmaskreps);
}
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n",
(s16_t)type, (s16_t)code));
ICMP_STATS_INC(icmp.proterr);
ICMP_STATS_INC(icmp.drop);
}
pbuf_free(p);
return;
lenerr:
pbuf_free(p);
ICMP_STATS_INC(icmp.lenerr);
MIB2_STATS_INC(mib2.icmpinerrors);
return;
#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING
icmperr:
pbuf_free(p);
ICMP_STATS_INC(icmp.err);
MIB2_STATS_INC(mib2.icmpinerrors);
return;
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */
}
/**
* Send an icmp 'destination unreachable' packet, called from ip_input() if
* the transport layer protocol is unknown and from udp_input() if the local
* port is not bound.
*
* @param p the input packet for which the 'unreachable' should be sent,
* p->payload pointing to the IP header
* @param t type of the 'unreachable' packet
*/
void
icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t)
{
MIB2_STATS_INC(mib2.icmpoutdestunreachs);
icmp_send_response(p, ICMP_DUR, t);
}
#if IP_FORWARD || IP_REASSEMBLY
/**
* Send a 'time exceeded' packet, called from ip_forward() if TTL is 0.
*
* @param p the input packet for which the 'time exceeded' should be sent,
* p->payload pointing to the IP header
* @param t type of the 'time exceeded' packet
*/
void
icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t)
{
MIB2_STATS_INC(mib2.icmpouttimeexcds);
icmp_send_response(p, ICMP_TE, t);
}
#endif /* IP_FORWARD || IP_REASSEMBLY */
/**
* Send an icmp packet in response to an incoming packet.
*
* @param p the input packet for which the 'unreachable' should be sent,
* p->payload pointing to the IP header
* @param type Type of the ICMP header
* @param code Code of the ICMP header
*/
static void
icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
{
struct pbuf *q;
struct ip_hdr *iphdr;
/* we can use the echo header here */
struct icmp_echo_hdr *icmphdr;
ip4_addr_t iphdr_src;
struct netif *netif;
/* increase number of messages attempted to send */
MIB2_STATS_INC(mib2.icmpoutmsgs);
/* ICMP header + IP header + 8 bytes of data */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
PBUF_RAM);
if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
MIB2_STATS_INC(mib2.icmpouterrors);
return;
}
LWIP_ASSERT("check that first pbuf can hold icmp message",
(q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE)));
iphdr = (struct ip_hdr *)p->payload;
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->src);
LWIP_DEBUGF(ICMP_DEBUG, (" to "));
ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->dest);
LWIP_DEBUGF(ICMP_DEBUG, ("\n"));
icmphdr = (struct icmp_echo_hdr *)q->payload;
icmphdr->type = type;
icmphdr->code = code;
icmphdr->id = 0;
icmphdr->seqno = 0;
/* copy fields from original packet */
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
ip4_addr_copy(iphdr_src, iphdr->src);
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
{
ip4_addr_t iphdr_dst;
ip4_addr_copy(iphdr_dst, iphdr->dest);
netif = ip4_route_src(&iphdr_dst, &iphdr_src);
}
#else
netif = ip4_route(&iphdr_src);
#endif
if (netif != NULL) {
/* calculate checksum */
icmphdr->chksum = 0;
#if CHECKSUM_GEN_ICMP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) {
icmphdr->chksum = inet_chksum(icmphdr, q->len);
}
#endif
ICMP_STATS_INC(icmp.xmit);
ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif);
}
pbuf_free(q);
}
#endif /* LWIP_IPV4 && LWIP_ICMP */
@@ -0,0 +1,801 @@
/**
* @file
* IGMP - Internet Group Management Protocol
*
* @defgroup igmp IGMP
* @ingroup ip4
* To be called from TCPIP thread
*/
/*
* Copyright (c) 2002 CITEL Technologies Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is a contribution to the lwIP TCP/IP stack.
* The Swedish Institute of Computer Science and Adam Dunkels
* are specifically granted permission to redistribute this
* source code.
*/
/*-------------------------------------------------------------
Note 1)
Although the rfc requires V1 AND V2 capability
we will only support v2 since now V1 is very old (August 1989)
V1 can be added if required
a debug print and statistic have been implemented to
show this up.
-------------------------------------------------------------
-------------------------------------------------------------
Note 2)
A query for a specific group address (as opposed to ALLHOSTS)
has now been implemented as I am unsure if it is required
a debug print and statistic have been implemented to
show this up.
-------------------------------------------------------------
-------------------------------------------------------------
Note 3)
The router alert rfc 2113 is implemented in outgoing packets
but not checked rigorously incoming
-------------------------------------------------------------
Steve Reynolds
------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
* RFC 988 - Host extensions for IP multicasting - V0
* RFC 1054 - Host extensions for IP multicasting -
* RFC 1112 - Host extensions for IP multicasting - V1
* RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard)
* RFC 3376 - Internet Group Management Protocol, Version 3 - V3
* RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+
* RFC 2113 - IP Router Alert Option -
*----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
* Includes
*----------------------------------------------------------------------------*/
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/igmp.h"
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/ip.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/stats.h"
#include "lwip/prot/igmp.h"
#include <string.h>
static struct igmp_group *igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr);
static err_t igmp_remove_group(struct netif *netif, struct igmp_group *group);
static void igmp_timeout(struct netif *netif, struct igmp_group *group);
static void igmp_start_timer(struct igmp_group *group, u8_t max_time);
static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp);
static err_t igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif);
static void igmp_send(struct netif *netif, struct igmp_group *group, u8_t type);
static ip4_addr_t allsystems;
static ip4_addr_t allrouters;
/**
* Initialize the IGMP module
*/
void
igmp_init(void)
{
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n"));
IP4_ADDR(&allsystems, 224, 0, 0, 1);
IP4_ADDR(&allrouters, 224, 0, 0, 2);
}
/**
* Start IGMP processing on interface
*
* @param netif network interface on which start IGMP processing
*/
err_t
igmp_start(struct netif *netif)
{
struct igmp_group *group;
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", (void *)netif));
group = igmp_lookup_group(netif, &allsystems);
if (group != NULL) {
group->group_state = IGMP_GROUP_IDLE_MEMBER;
group->use++;
/* Allow the igmp messages at the MAC level */
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD "));
ip4_addr_debug_print_val(IGMP_DEBUG, allsystems);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif));
netif->igmp_mac_filter(netif, &allsystems, NETIF_ADD_MAC_FILTER);
}
return ERR_OK;
}
return ERR_MEM;
}
/**
* Stop IGMP processing on interface
*
* @param netif network interface on which stop IGMP processing
*/
err_t
igmp_stop(struct netif *netif)
{
struct igmp_group *group = netif_igmp_data(netif);
netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, NULL);
while (group != NULL) {
struct igmp_group *next = group->next; /* avoid use-after-free below */
/* disable the group at the MAC level */
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL "));
ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif));
netif->igmp_mac_filter(netif, &(group->group_address), NETIF_DEL_MAC_FILTER);
}
/* free group */
memp_free(MEMP_IGMP_GROUP, group);
/* move to "next" */
group = next;
}
return ERR_OK;
}
/**
* Report IGMP memberships for this interface
*
* @param netif network interface on which report IGMP memberships
*/
void
igmp_report_groups(struct netif *netif)
{
struct igmp_group *group = netif_igmp_data(netif);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", (void *)netif));
/* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
if (group != NULL) {
group = group->next;
}
while (group != NULL) {
igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
group = group->next;
}
}
/**
* Search for a group in the netif's igmp group list
*
* @param ifp the network interface for which to look
* @param addr the group ip address to search for
* @return a struct igmp_group* if the group has been found,
* NULL if the group wasn't found.
*/
struct igmp_group *
igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr)
{
struct igmp_group *group = netif_igmp_data(ifp);
while (group != NULL) {
if (ip4_addr_cmp(&(group->group_address), addr)) {
return group;
}
group = group->next;
}
/* to be clearer, we return NULL here instead of
* 'group' (which is also NULL at this point).
*/
return NULL;
}
/**
* Search for a specific igmp group and create a new one if not found-
*
* @param ifp the network interface for which to look
* @param addr the group ip address to search
* @return a struct igmp_group*,
* NULL on memory error.
*/
static struct igmp_group *
igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
{
struct igmp_group *group;
struct igmp_group *list_head = netif_igmp_data(ifp);
/* Search if the group already exists */
group = igmp_lookfor_group(ifp, addr);
if (group != NULL) {
/* Group already exists. */
return group;
}
/* Group doesn't exist yet, create a new one */
group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP);
if (group != NULL) {
ip4_addr_set(&(group->group_address), addr);
group->timer = 0; /* Not running */
group->group_state = IGMP_GROUP_NON_MEMBER;
group->last_reporter_flag = 0;
group->use = 0;
/* Ensure allsystems group is always first in list */
if (list_head == NULL) {
/* this is the first entry in linked list */
LWIP_ASSERT("igmp_lookup_group: first group must be allsystems",
(ip4_addr_cmp(addr, &allsystems) != 0));
group->next = NULL;
netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group);
} else {
/* append _after_ first entry */
LWIP_ASSERT("igmp_lookup_group: all except first group must not be allsystems",
(ip4_addr_cmp(addr, &allsystems) == 0));
group->next = list_head->next;
list_head->next = group;
}
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group ? "" : "impossible to ")));
ip4_addr_debug_print(IGMP_DEBUG, addr);
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)ifp));
return group;
}
/**
* Remove a group from netif's igmp group list, but don't free it yet
*
* @param group the group to remove from the netif's igmp group list
* @return ERR_OK if group was removed from the list, an err_t otherwise
*/
static err_t
igmp_remove_group(struct netif *netif, struct igmp_group *group)
{
err_t err = ERR_OK;
struct igmp_group *tmp_group;
/* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
for (tmp_group = netif_igmp_data(netif); tmp_group != NULL; tmp_group = tmp_group->next) {
if (tmp_group->next == group) {
tmp_group->next = group->next;
break;
}
}
/* Group not found in netif's igmp group list */
if (tmp_group == NULL) {
err = ERR_ARG;
}
return err;
}
/**
* Called from ip_input() if a new IGMP packet is received.
*
* @param p received igmp packet, p->payload pointing to the igmp header
* @param inp network interface on which the packet was received
* @param dest destination ip address of the igmp packet
*/
void
igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest)
{
struct igmp_msg *igmp;
struct igmp_group *group;
struct igmp_group *groupref;
IGMP_STATS_INC(igmp.recv);
/* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */
if (p->len < IGMP_MINLEN) {
pbuf_free(p);
IGMP_STATS_INC(igmp.lenerr);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n"));
return;
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from "));
ip4_addr_debug_print_val(IGMP_DEBUG, ip4_current_header()->src);
LWIP_DEBUGF(IGMP_DEBUG, (" to address "));
ip4_addr_debug_print_val(IGMP_DEBUG, ip4_current_header()->dest);
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)inp));
/* Now calculate and check the checksum */
igmp = (struct igmp_msg *)p->payload;
if (inet_chksum(igmp, p->len)) {
pbuf_free(p);
IGMP_STATS_INC(igmp.chkerr);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n"));
return;
}
/* Packet is ok so find an existing group */
group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */
/* If group can be found or create... */
if (!group) {
pbuf_free(p);
IGMP_STATS_INC(igmp.drop);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n"));
return;
}
/* NOW ACT ON THE INCOMING MESSAGE TYPE... */
switch (igmp->igmp_msgtype) {
case IGMP_MEMB_QUERY:
/* IGMP_MEMB_QUERY to the "all systems" address ? */
if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) {
/* THIS IS THE GENERAL QUERY */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
if (igmp->igmp_maxresp == 0) {
IGMP_STATS_INC(igmp.rx_v1);
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n"));
igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR;
} else {
IGMP_STATS_INC(igmp.rx_general);
}
groupref = netif_igmp_data(inp);
/* Do not send messages on the all systems group address! */
/* Skip the first group in the list, it is always the allsystems group added in igmp_start() */
if (groupref != NULL) {
groupref = groupref->next;
}
while (groupref) {
igmp_delaying_member(groupref, igmp->igmp_maxresp);
groupref = groupref->next;
}
} else {
/* IGMP_MEMB_QUERY to a specific group ? */
if (!ip4_addr_isany(&igmp->igmp_group_address)) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group "));
ip4_addr_debug_print_val(IGMP_DEBUG, igmp->igmp_group_address);
if (ip4_addr_cmp(dest, &allsystems)) {
ip4_addr_t groupaddr;
LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
/* we first need to re-look for the group since we used dest last time */
ip4_addr_copy(groupaddr, igmp->igmp_group_address);
group = igmp_lookfor_group(inp, &groupaddr);
} else {
LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp)));
}
if (group != NULL) {
IGMP_STATS_INC(igmp.rx_group);
igmp_delaying_member(group, igmp->igmp_maxresp);
} else {
IGMP_STATS_INC(igmp.drop);
}
} else {
IGMP_STATS_INC(igmp.proterr);
}
}
break;
case IGMP_V2_MEMB_REPORT:
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n"));
IGMP_STATS_INC(igmp.rx_report);
if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
/* This is on a specific group we have already looked up */
group->timer = 0; /* stopped */
group->group_state = IGMP_GROUP_IDLE_MEMBER;
group->last_reporter_flag = 0;
}
break;
default:
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n",
igmp->igmp_msgtype, group->group_state, (void *)&group, (void *)inp));
IGMP_STATS_INC(igmp.proterr);
break;
}
pbuf_free(p);
return;
}
/**
* @ingroup igmp
* Join a group on one network interface.
*
* @param ifaddr ip address of the network interface which should join a new group
* @param groupaddr the ip address of the group which to join
* @return ERR_OK if group was joined on the netif(s), an err_t otherwise
*/
err_t
igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
{
err_t err = ERR_VAL; /* no matching interface */
struct netif *netif;
LWIP_ASSERT_CORE_LOCKED();
/* make sure it is multicast address */
LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* loop through netif's */
NETIF_FOREACH(netif) {
/* Should we join this interface ? */
if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
err = igmp_joingroup_netif(netif, groupaddr);
if (err != ERR_OK) {
/* Return an error even if some network interfaces are joined */
/** @todo undo any other netif already joined */
return err;
}
}
}
return err;
}
/**
* @ingroup igmp
* Join a group on one network interface.
*
* @param netif the network interface which should join a new group
* @param groupaddr the ip address of the group which to join
* @return ERR_OK if group was joined on the netif, an err_t otherwise
*/
err_t
igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
{
struct igmp_group *group;
LWIP_ASSERT_CORE_LOCKED();
/* make sure it is multicast address */
LWIP_ERROR("igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR("igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* make sure it is an igmp-enabled netif */
LWIP_ERROR("igmp_joingroup_netif: attempt to join on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
/* find group or create a new one if not found */
group = igmp_lookup_group(netif, groupaddr);
if (group != NULL) {
/* This should create a new group, check the state to make sure */
if (group->group_state != IGMP_GROUP_NON_MEMBER) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to group not in state IGMP_GROUP_NON_MEMBER\n"));
} else {
/* OK - it was new group */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to new group: "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
/* If first use of the group, allow the group at the MAC level */
if ((group->use == 0) && (netif->igmp_mac_filter != NULL)) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: igmp_mac_filter(ADD "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif));
netif->igmp_mac_filter(netif, groupaddr, NETIF_ADD_MAC_FILTER);
}
IGMP_STATS_INC(igmp.tx_join);
igmp_send(netif, group, IGMP_V2_MEMB_REPORT);
igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
/* Need to work out where this timer comes from */
group->group_state = IGMP_GROUP_DELAYING_MEMBER;
}
/* Increment group use */
group->use++;
/* Join on this interface */
return ERR_OK;
} else {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: Not enough memory to join to group\n"));
return ERR_MEM;
}
}
/**
* @ingroup igmp
* Leave a group on one network interface.
*
* @param ifaddr ip address of the network interface which should leave a group
* @param groupaddr the ip address of the group which to leave
* @return ERR_OK if group was left on the netif(s), an err_t otherwise
*/
err_t
igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr)
{
err_t err = ERR_VAL; /* no matching interface */
struct netif *netif;
LWIP_ASSERT_CORE_LOCKED();
/* make sure it is multicast address */
LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* loop through netif's */
NETIF_FOREACH(netif) {
/* Should we leave this interface ? */
if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) {
err_t res = igmp_leavegroup_netif(netif, groupaddr);
if (err != ERR_OK) {
/* Store this result if we have not yet gotten a success */
err = res;
}
}
}
return err;
}
/**
* @ingroup igmp
* Leave a group on one network interface.
*
* @param netif the network interface which should leave a group
* @param groupaddr the ip address of the group which to leave
* @return ERR_OK if group was left on the netif, an err_t otherwise
*/
err_t
igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
{
struct igmp_group *group;
LWIP_ASSERT_CORE_LOCKED();
/* make sure it is multicast address */
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;);
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
/* make sure it is an igmp-enabled netif */
LWIP_ERROR("igmp_leavegroup_netif: attempt to leave on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;);
/* find group */
group = igmp_lookfor_group(netif, groupaddr);
if (group != NULL) {
/* Only send a leave if the flag is set according to the state diagram */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: Leaving group: "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
/* If there is no other use of the group */
if (group->use <= 1) {
/* Remove the group from the list */
igmp_remove_group(netif, group);
/* If we are the last reporter for this group */
if (group->last_reporter_flag) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: sending leaving group\n"));
IGMP_STATS_INC(igmp.tx_leave);
igmp_send(netif, group, IGMP_LEAVE_GROUP);
}
/* Disable the group at the MAC level */
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: igmp_mac_filter(DEL "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void *)netif));
netif->igmp_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER);
}
/* Free group struct */
memp_free(MEMP_IGMP_GROUP, group);
} else {
/* Decrement group use */
group->use--;
}
return ERR_OK;
} else {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: not member of group\n"));
return ERR_VAL;
}
}
/**
* The igmp timer function (both for NO_SYS=1 and =0)
* Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default).
*/
void
igmp_tmr(void)
{
struct netif *netif;
NETIF_FOREACH(netif) {
struct igmp_group *group = netif_igmp_data(netif);
while (group != NULL) {
if (group->timer > 0) {
group->timer--;
if (group->timer == 0) {
igmp_timeout(netif, group);
}
}
group = group->next;
}
}
}
/**
* Called if a timeout for one group is reached.
* Sends a report for this group.
*
* @param group an igmp_group for which a timeout is reached
*/
static void
igmp_timeout(struct netif *netif, struct igmp_group *group)
{
/* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group
(unless it is the allsystems group) */
if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
(!(ip4_addr_cmp(&(group->group_address), &allsystems)))) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address "));
ip4_addr_debug_print_val(IGMP_DEBUG, group->group_address);
LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void *)netif));
group->group_state = IGMP_GROUP_IDLE_MEMBER;
IGMP_STATS_INC(igmp.tx_report);
igmp_send(netif, group, IGMP_V2_MEMB_REPORT);
}
}
/**
* Start a timer for an igmp group
*
* @param group the igmp_group for which to start a timer
* @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with
* every call to igmp_tmr())
*/
static void
igmp_start_timer(struct igmp_group *group, u8_t max_time)
{
#ifdef LWIP_RAND
group->timer = (u16_t)(max_time > 2 ? (LWIP_RAND() % max_time) : 1);
#else /* LWIP_RAND */
/* ATTENTION: use this only if absolutely necessary! */
group->timer = max_time / 2;
#endif /* LWIP_RAND */
if (group->timer == 0) {
group->timer = 1;
}
}
/**
* Delaying membership report for a group if necessary
*
* @param group the igmp_group for which "delaying" membership report
* @param maxresp query delay
*/
static void
igmp_delaying_member(struct igmp_group *group, u8_t maxresp)
{
if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) ||
((group->group_state == IGMP_GROUP_DELAYING_MEMBER) &&
((group->timer == 0) || (maxresp < group->timer)))) {
igmp_start_timer(group, maxresp);
group->group_state = IGMP_GROUP_DELAYING_MEMBER;
}
}
/**
* Sends an IP packet on a network interface. This function constructs the IP header
* and calculates the IP header checksum. If the source IP address is NULL,
* the IP address of the outgoing network interface is filled in as source address.
*
* @param p the packet to send (p->payload points to the data, e.g. next
protocol header; if dest == LWIP_IP_HDRINCL, p already includes an
IP header and p->payload points to that IP header)
* @param src the source IP address to send from (if src == IP4_ADDR_ANY, the
* IP address of the netif used to send is used as source address)
* @param dest the destination IP address to send the packet to
* @param netif the netif on which to send this packet
* @return ERR_OK if the packet was sent OK
* ERR_BUF if p doesn't have enough space for IP/LINK headers
* returns errors returned by netif->output
*/
static err_t
igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif)
{
/* This is the "router alert" option */
u16_t ra[2];
ra[0] = PP_HTONS(ROUTER_ALERT);
ra[1] = 0x0000; /* Router shall examine packet */
IGMP_STATS_INC(igmp.xmit);
return ip4_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN);
}
/**
* Send an igmp packet to a specific group.
*
* @param group the group to which to send the packet
* @param type the type of igmp packet to send
*/
static void
igmp_send(struct netif *netif, struct igmp_group *group, u8_t type)
{
struct pbuf *p = NULL;
struct igmp_msg *igmp = NULL;
ip4_addr_t src = *IP4_ADDR_ANY4;
ip4_addr_t *dest = NULL;
/* IP header + "router alert" option + IGMP header */
p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM);
if (p) {
igmp = (struct igmp_msg *)p->payload;
LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg",
(p->len >= sizeof(struct igmp_msg)));
ip4_addr_copy(src, *netif_ip4_addr(netif));
if (type == IGMP_V2_MEMB_REPORT) {
dest = &(group->group_address);
ip4_addr_copy(igmp->igmp_group_address, group->group_address);
group->last_reporter_flag = 1; /* Remember we were the last to report */
} else {
if (type == IGMP_LEAVE_GROUP) {
dest = &allrouters;
ip4_addr_copy(igmp->igmp_group_address, group->group_address);
}
}
if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) {
igmp->igmp_msgtype = type;
igmp->igmp_maxresp = 0;
igmp->igmp_checksum = 0;
igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN);
igmp_ip_output_if(p, &src, dest, netif);
}
pbuf_free(p);
} else {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n"));
IGMP_STATS_INC(igmp.memerr);
}
}
#endif /* LWIP_IPV4 && LWIP_IGMP */
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,321 @@
/**
* @file
* This is the IPv4 address tools implementation.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_IPV4
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
/* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */
const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY);
const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST);
/**
* Determine if an address is a broadcast address on a network interface
*
* @param addr address to be checked
* @param netif the network interface against which the address is checked
* @return returns non-zero if the address is a broadcast address
*/
u8_t
ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif)
{
ip4_addr_t ipaddr;
ip4_addr_set_u32(&ipaddr, addr);
/* all ones (broadcast) or all zeroes (old skool broadcast) */
if ((~addr == IPADDR_ANY) ||
(addr == IPADDR_ANY)) {
return 1;
/* no broadcast support on this network interface? */
} else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
/* the given address cannot be a broadcast address
* nor can we check against any broadcast addresses */
return 0;
/* address matches network interface address exactly? => no broadcast */
} else if (addr == ip4_addr_get_u32(netif_ip4_addr(netif))) {
return 0;
/* on the same (sub) network... */
} else if (ip4_addr_netcmp(&ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif))
/* ...and host identifier bits are all ones? =>... */
&& ((addr & ~ip4_addr_get_u32(netif_ip4_netmask(netif))) ==
(IPADDR_BROADCAST & ~ip4_addr_get_u32(netif_ip4_netmask(netif))))) {
/* => network broadcast address */
return 1;
} else {
return 0;
}
}
/** Checks if a netmask is valid (starting with ones, then only zeros)
*
* @param netmask the IPv4 netmask to check (in network byte order!)
* @return 1 if the netmask is valid, 0 if it is not
*/
u8_t
ip4_addr_netmask_valid(u32_t netmask)
{
u32_t mask;
u32_t nm_hostorder = lwip_htonl(netmask);
/* first, check for the first zero */
for (mask = 1UL << 31 ; mask != 0; mask >>= 1) {
if ((nm_hostorder & mask) == 0) {
break;
}
}
/* then check that there is no one */
for (; mask != 0; mask >>= 1) {
if ((nm_hostorder & mask) != 0) {
/* there is a one after the first zero -> invalid */
return 0;
}
}
/* no one after the first zero -> valid */
return 1;
}
/**
* Ascii internet address interpretation routine.
* The value returned is in network order.
*
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
* @return ip address in network order
*/
u32_t
ipaddr_addr(const char *cp)
{
ip4_addr_t val;
if (ip4addr_aton(cp, &val)) {
return ip4_addr_get_u32(&val);
}
return (IPADDR_NONE);
}
/**
* Check whether "cp" is a valid ascii representation
* of an Internet address and convert to a binary address.
* Returns 1 if the address is valid, 0 if not.
* This replaces inet_addr, the return value from which
* cannot distinguish between failure and a local broadcast address.
*
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
* @param addr pointer to which to save the ip address in network order
* @return 1 if cp could be converted to addr, 0 on failure
*/
int
ip4addr_aton(const char *cp, ip4_addr_t *addr)
{
u32_t val;
u8_t base;
char c;
u32_t parts[4];
u32_t *pp = parts;
c = *cp;
for (;;) {
/*
* Collect number up to ``.''.
* Values are specified as for C:
* 0x=hex, 0=octal, 1-9=decimal.
*/
if (!lwip_isdigit(c)) {
return 0;
}
val = 0;
base = 10;
if (c == '0') {
c = *++cp;
if (c == 'x' || c == 'X') {
base = 16;
c = *++cp;
} else {
base = 8;
}
}
for (;;) {
if (lwip_isdigit(c)) {
val = (val * base) + (u32_t)(c - '0');
c = *++cp;
} else if (base == 16 && lwip_isxdigit(c)) {
val = (val << 4) | (u32_t)(c + 10 - (lwip_islower(c) ? 'a' : 'A'));
c = *++cp;
} else {
break;
}
}
if (c == '.') {
/*
* Internet format:
* a.b.c.d
* a.b.c (with c treated as 16 bits)
* a.b (with b treated as 24 bits)
*/
if (pp >= parts + 3) {
return 0;
}
*pp++ = val;
c = *++cp;
} else {
break;
}
}
/*
* Check for trailing characters.
*/
if (c != '\0' && !lwip_isspace(c)) {
return 0;
}
/*
* Concoct the address according to
* the number of parts specified.
*/
switch (pp - parts + 1) {
case 0:
return 0; /* initial nondigit */
case 1: /* a -- 32 bits */
break;
case 2: /* a.b -- 8.24 bits */
if (val > 0xffffffUL) {
return 0;
}
if (parts[0] > 0xff) {
return 0;
}
val |= parts[0] << 24;
break;
case 3: /* a.b.c -- 8.8.16 bits */
if (val > 0xffff) {
return 0;
}
if ((parts[0] > 0xff) || (parts[1] > 0xff)) {
return 0;
}
val |= (parts[0] << 24) | (parts[1] << 16);
break;
case 4: /* a.b.c.d -- 8.8.8.8 bits */
if (val > 0xff) {
return 0;
}
if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) {
return 0;
}
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
break;
default:
LWIP_ASSERT("unhandled", 0);
break;
}
if (addr) {
ip4_addr_set_u32(addr, lwip_htonl(val));
}
return 1;
}
/**
* Convert numeric IP address into decimal dotted ASCII representation.
* returns ptr to static buffer; not reentrant!
*
* @param addr ip address in network order to convert
* @return pointer to a global static (!) buffer that holds the ASCII
* representation of addr
*/
char *
ip4addr_ntoa(const ip4_addr_t *addr)
{
static char str[IP4ADDR_STRLEN_MAX];
return ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX);
}
/**
* Same as ip4addr_ntoa, but reentrant since a user-supplied buffer is used.
*
* @param addr ip address in network order to convert
* @param buf target buffer where the string is stored
* @param buflen length of buf
* @return either pointer to buf which now holds the ASCII
* representation of addr or NULL if buf was too small
*/
char *
ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
{
u32_t s_addr;
char inv[3];
char *rp;
u8_t *ap;
u8_t rem;
u8_t n;
u8_t i;
int len = 0;
s_addr = ip4_addr_get_u32(addr);
rp = buf;
ap = (u8_t *)&s_addr;
for (n = 0; n < 4; n++) {
i = 0;
do {
rem = *ap % (u8_t)10;
*ap /= (u8_t)10;
inv[i++] = (char)('0' + rem);
} while (*ap);
while (i--) {
if (len++ >= buflen) {
return NULL;
}
*rp++ = inv[i];
}
if (len++ >= buflen) {
return NULL;
}
*rp++ = '.';
ap++;
}
*--rp = 0;
return buf;
}
#endif /* LWIP_IPV4 */
@@ -0,0 +1,894 @@
/**
* @file
* This is the IPv4 packet segmentation and reassembly implementation.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Jani Monoses <jani@iv.ro>
* Simon Goldschmidt
* original reassembly code by Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_IPV4
#include "lwip/ip4_frag.h"
#include "lwip/def.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/stats.h"
#include "lwip/icmp.h"
#include <string.h>
#if IP_REASSEMBLY
/**
* The IP reassembly code currently has the following limitations:
* - IP header options are not supported
* - fragments must not overlap (e.g. due to different routes),
* currently, overlapping or duplicate fragments are thrown away
* if IP_REASS_CHECK_OVERLAP=1 (the default)!
*
* @todo: work with IP header options
*/
/** Setting this to 0, you can turn off checking the fragments for overlapping
* regions. The code gets a little smaller. Only use this if you know that
* overlapping won't occur on your network! */
#ifndef IP_REASS_CHECK_OVERLAP
#define IP_REASS_CHECK_OVERLAP 1
#endif /* IP_REASS_CHECK_OVERLAP */
/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is
* full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller.
* Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA
* is set to 1, so one datagram can be reassembled at a time, only. */
#ifndef IP_REASS_FREE_OLDEST
#define IP_REASS_FREE_OLDEST 1
#endif /* IP_REASS_FREE_OLDEST */
#define IP_REASS_FLAG_LASTFRAG 0x01
#define IP_REASS_VALIDATE_TELEGRAM_FINISHED 1
#define IP_REASS_VALIDATE_PBUF_QUEUED 0
#define IP_REASS_VALIDATE_PBUF_DROPPED -1
/** This is a helper struct which holds the starting
* offset and the ending offset of this fragment to
* easily chain the fragments.
* It has the same packing requirements as the IP header, since it replaces
* the IP header in memory in incoming fragments (after copying it) to keep
* track of the various fragments. (-> If the IP header doesn't need packing,
* this struct doesn't need packing, too.)
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip_reass_helper {
PACK_STRUCT_FIELD(struct pbuf *next_pbuf);
PACK_STRUCT_FIELD(u16_t start);
PACK_STRUCT_FIELD(u16_t end);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \
(ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \
ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \
IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0
/* global variables */
static struct ip_reassdata *reassdatagrams;
static u16_t ip_reass_pbufcount;
/* function prototypes */
static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev);
/**
* Reassembly timer base function
* for both NO_SYS == 0 and 1 (!).
*
* Should be called every 1000 msec (defined by IP_TMR_INTERVAL).
*/
void
ip_reass_tmr(void)
{
struct ip_reassdata *r, *prev = NULL;
r = reassdatagrams;
while (r != NULL) {
/* Decrement the timer. Once it reaches 0,
* clean up the incomplete fragment assembly */
if (r->timer > 0) {
r->timer--;
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n", (u16_t)r->timer));
prev = r;
r = r->next;
} else {
/* reassembly timed out */
struct ip_reassdata *tmp;
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n"));
tmp = r;
/* get the next pointer before freeing */
r = r->next;
/* free the helper struct and all enqueued pbufs */
ip_reass_free_complete_datagram(tmp, prev);
}
}
}
/**
* Free a datagram (struct ip_reassdata) and all its pbufs.
* Updates the total count of enqueued pbufs (ip_reass_pbufcount),
* SNMP counters and sends an ICMP time exceeded packet.
*
* @param ipr datagram to free
* @param prev the previous datagram in the linked list
* @return the number of pbufs freed
*/
static int
ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
{
u16_t pbufs_freed = 0;
u16_t clen;
struct pbuf *p;
struct ip_reass_helper *iprh;
LWIP_ASSERT("prev != ipr", prev != ipr);
if (prev != NULL) {
LWIP_ASSERT("prev->next == ipr", prev->next == ipr);
}
MIB2_STATS_INC(mib2.ipreasmfails);
#if LWIP_ICMP
iprh = (struct ip_reass_helper *)ipr->p->payload;
if (iprh->start == 0) {
/* The first fragment was received, send ICMP time exceeded. */
/* First, de-queue the first pbuf from r->p. */
p = ipr->p;
ipr->p = iprh->next_pbuf;
/* Then, copy the original header into it. */
SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN);
icmp_time_exceeded(p, ICMP_TE_FRAG);
clen = pbuf_clen(p);
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
pbufs_freed = (u16_t)(pbufs_freed + clen);
pbuf_free(p);
}
#endif /* LWIP_ICMP */
/* First, free all received pbufs. The individual pbufs need to be released
separately as they have not yet been chained */
p = ipr->p;
while (p != NULL) {
struct pbuf *pcur;
iprh = (struct ip_reass_helper *)p->payload;
pcur = p;
/* get the next pointer before freeing */
p = iprh->next_pbuf;
clen = pbuf_clen(pcur);
LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff);
pbufs_freed = (u16_t)(pbufs_freed + clen);
pbuf_free(pcur);
}
/* Then, unchain the struct ip_reassdata from the list and free it. */
ip_reass_dequeue_datagram(ipr, prev);
LWIP_ASSERT("ip_reass_pbufcount >= pbufs_freed", ip_reass_pbufcount >= pbufs_freed);
ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount - pbufs_freed);
return pbufs_freed;
}
#if IP_REASS_FREE_OLDEST
/**
* Free the oldest datagram to make room for enqueueing new fragments.
* The datagram 'fraghdr' belongs to is not freed!
*
* @param fraghdr IP header of the current fragment
* @param pbufs_needed number of pbufs needed to enqueue
* (used for freeing other datagrams if not enough space)
* @return the number of pbufs freed
*/
static int
ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed)
{
/* @todo Can't we simply remove the last datagram in the
* linked list behind reassdatagrams?
*/
struct ip_reassdata *r, *oldest, *prev, *oldest_prev;
int pbufs_freed = 0, pbufs_freed_current;
int other_datagrams;
/* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs,
* but don't free the datagram that 'fraghdr' belongs to! */
do {
oldest = NULL;
prev = NULL;
oldest_prev = NULL;
other_datagrams = 0;
r = reassdatagrams;
while (r != NULL) {
if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) {
/* Not the same datagram as fraghdr */
other_datagrams++;
if (oldest == NULL) {
oldest = r;
oldest_prev = prev;
} else if (r->timer <= oldest->timer) {
/* older than the previous oldest */
oldest = r;
oldest_prev = prev;
}
}
if (r->next != NULL) {
prev = r;
}
r = r->next;
}
if (oldest != NULL) {
pbufs_freed_current = ip_reass_free_complete_datagram(oldest, oldest_prev);
pbufs_freed += pbufs_freed_current;
}
} while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1));
return pbufs_freed;
}
#endif /* IP_REASS_FREE_OLDEST */
/**
* Enqueues a new fragment into the fragment queue
* @param fraghdr points to the new fragments IP hdr
* @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space)
* @return A pointer to the queue location into which the fragment was enqueued
*/
static struct ip_reassdata *
ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen)
{
struct ip_reassdata *ipr;
#if ! IP_REASS_FREE_OLDEST
LWIP_UNUSED_ARG(clen);
#endif
/* No matching previous fragment found, allocate a new reassdata struct */
ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA);
if (ipr == NULL) {
#if IP_REASS_FREE_OLDEST
if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) {
ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA);
}
if (ipr == NULL)
#endif /* IP_REASS_FREE_OLDEST */
{
IPFRAG_STATS_INC(ip_frag.memerr);
LWIP_DEBUGF(IP_REASS_DEBUG, ("Failed to alloc reassdata struct\n"));
return NULL;
}
}
memset(ipr, 0, sizeof(struct ip_reassdata));
ipr->timer = IP_REASS_MAXAGE;
/* enqueue the new structure to the front of the list */
ipr->next = reassdatagrams;
reassdatagrams = ipr;
/* copy the ip header for later tests and input */
/* @todo: no ip options supported? */
SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN);
return ipr;
}
/**
* Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs.
* @param ipr points to the queue entry to dequeue
*/
static void
ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev)
{
/* dequeue the reass struct */
if (reassdatagrams == ipr) {
/* it was the first in the list */
reassdatagrams = ipr->next;
} else {
/* it wasn't the first, so it must have a valid 'prev' */
LWIP_ASSERT("sanity check linked list", prev != NULL);
prev->next = ipr->next;
}
/* now we can free the ip_reassdata struct */
memp_free(MEMP_REASSDATA, ipr);
}
/**
* Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list
* will grow over time as new pbufs are rx.
* Also checks that the datagram passes basic continuity checks (if the last
* fragment was received at least once).
* @param ipr points to the reassembly state
* @param new_p points to the pbuf for the current fragment
* @param is_last is 1 if this pbuf has MF==0 (ipr->flags not updated yet)
* @return see IP_REASS_VALIDATE_* defines
*/
static int
ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p, int is_last)
{
struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev = NULL;
struct pbuf *q;
u16_t offset, len;
u8_t hlen;
struct ip_hdr *fraghdr;
int valid = 1;
/* Extract length and fragment offset from current fragment */
fraghdr = (struct ip_hdr *)new_p->payload;
len = lwip_ntohs(IPH_LEN(fraghdr));
hlen = IPH_HL_BYTES(fraghdr);
if (hlen > len) {
/* invalid datagram */
return IP_REASS_VALIDATE_PBUF_DROPPED;
}
len = (u16_t)(len - hlen);
offset = IPH_OFFSET_BYTES(fraghdr);
/* overwrite the fragment's ip header from the pbuf with our helper struct,
* and setup the embedded helper structure. */
/* make sure the struct ip_reass_helper fits into the IP header */
LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN",
sizeof(struct ip_reass_helper) <= IP_HLEN);
iprh = (struct ip_reass_helper *)new_p->payload;
iprh->next_pbuf = NULL;
iprh->start = offset;
iprh->end = (u16_t)(offset + len);
if (iprh->end < offset) {
/* u16_t overflow, cannot handle this */
return IP_REASS_VALIDATE_PBUF_DROPPED;
}
/* Iterate through until we either get to the end of the list (append),
* or we find one with a larger offset (insert). */
for (q = ipr->p; q != NULL;) {
iprh_tmp = (struct ip_reass_helper *)q->payload;
if (iprh->start < iprh_tmp->start) {
/* the new pbuf should be inserted before this */
iprh->next_pbuf = q;
if (iprh_prev != NULL) {
/* not the fragment with the lowest offset */
#if IP_REASS_CHECK_OVERLAP
if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) {
/* fragment overlaps with previous or following, throw away */
return IP_REASS_VALIDATE_PBUF_DROPPED;
}
#endif /* IP_REASS_CHECK_OVERLAP */
iprh_prev->next_pbuf = new_p;
if (iprh_prev->end != iprh->start) {
/* There is a fragment missing between the current
* and the previous fragment */
valid = 0;
}
} else {
#if IP_REASS_CHECK_OVERLAP
if (iprh->end > iprh_tmp->start) {
/* fragment overlaps with following, throw away */
return IP_REASS_VALIDATE_PBUF_DROPPED;
}
#endif /* IP_REASS_CHECK_OVERLAP */
/* fragment with the lowest offset */
ipr->p = new_p;
}
break;
} else if (iprh->start == iprh_tmp->start) {
/* received the same datagram twice: no need to keep the datagram */
return IP_REASS_VALIDATE_PBUF_DROPPED;
#if IP_REASS_CHECK_OVERLAP
} else if (iprh->start < iprh_tmp->end) {
/* overlap: no need to keep the new datagram */
return IP_REASS_VALIDATE_PBUF_DROPPED;
#endif /* IP_REASS_CHECK_OVERLAP */
} else {
/* Check if the fragments received so far have no holes. */
if (iprh_prev != NULL) {
if (iprh_prev->end != iprh_tmp->start) {
/* There is a fragment missing between the current
* and the previous fragment */
valid = 0;
}
}
}
q = iprh_tmp->next_pbuf;
iprh_prev = iprh_tmp;
}
/* If q is NULL, then we made it to the end of the list. Determine what to do now */
if (q == NULL) {
if (iprh_prev != NULL) {
/* this is (for now), the fragment with the highest offset:
* chain it to the last fragment */
#if IP_REASS_CHECK_OVERLAP
LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start);
#endif /* IP_REASS_CHECK_OVERLAP */
iprh_prev->next_pbuf = new_p;
if (iprh_prev->end != iprh->start) {
valid = 0;
}
} else {
#if IP_REASS_CHECK_OVERLAP
LWIP_ASSERT("no previous fragment, this must be the first fragment!",
ipr->p == NULL);
#endif /* IP_REASS_CHECK_OVERLAP */
/* this is the first fragment we ever received for this ip datagram */
ipr->p = new_p;
}
}
/* At this point, the validation part begins: */
/* If we already received the last fragment */
if (is_last || ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0)) {
/* and had no holes so far */
if (valid) {
/* then check if the rest of the fragments is here */
/* Check if the queue starts with the first datagram */
if ((ipr->p == NULL) || (((struct ip_reass_helper *)ipr->p->payload)->start != 0)) {
valid = 0;
} else {
/* and check that there are no holes after this datagram */
iprh_prev = iprh;
q = iprh->next_pbuf;
while (q != NULL) {
iprh = (struct ip_reass_helper *)q->payload;
if (iprh_prev->end != iprh->start) {
valid = 0;
break;
}
iprh_prev = iprh;
q = iprh->next_pbuf;
}
/* if still valid, all fragments are received
* (because to the MF==0 already arrived */
if (valid) {
LWIP_ASSERT("sanity check", ipr->p != NULL);
LWIP_ASSERT("sanity check",
((struct ip_reass_helper *)ipr->p->payload) != iprh);
LWIP_ASSERT("validate_datagram:next_pbuf!=NULL",
iprh->next_pbuf == NULL);
}
}
}
/* If valid is 0 here, there are some fragments missing in the middle
* (since MF == 0 has already arrived). Such datagrams simply time out if
* no more fragments are received... */
return valid ? IP_REASS_VALIDATE_TELEGRAM_FINISHED : IP_REASS_VALIDATE_PBUF_QUEUED;
}
/* If we come here, not all fragments were received, yet! */
return IP_REASS_VALIDATE_PBUF_QUEUED; /* not yet valid! */
}
/**
* Reassembles incoming IP fragments into an IP datagram.
*
* @param p points to a pbuf chain of the fragment
* @return NULL if reassembly is incomplete, ? otherwise
*/
struct pbuf *
ip4_reass(struct pbuf *p)
{
struct pbuf *r;
struct ip_hdr *fraghdr;
struct ip_reassdata *ipr;
struct ip_reass_helper *iprh;
u16_t offset, len, clen;
u8_t hlen;
int valid;
int is_last;
IPFRAG_STATS_INC(ip_frag.recv);
MIB2_STATS_INC(mib2.ipreasmreqds);
fraghdr = (struct ip_hdr *)p->payload;
if (IPH_HL_BYTES(fraghdr) != IP_HLEN) {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: IP options currently not supported!\n"));
IPFRAG_STATS_INC(ip_frag.err);
goto nullreturn;
}
offset = IPH_OFFSET_BYTES(fraghdr);
len = lwip_ntohs(IPH_LEN(fraghdr));
hlen = IPH_HL_BYTES(fraghdr);
if (hlen > len) {
/* invalid datagram */
goto nullreturn;
}
len = (u16_t)(len - hlen);
/* Check if we are allowed to enqueue more datagrams. */
clen = pbuf_clen(p);
if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) {
#if IP_REASS_FREE_OLDEST
if (!ip_reass_remove_oldest_datagram(fraghdr, clen) ||
((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS))
#endif /* IP_REASS_FREE_OLDEST */
{
/* No datagram could be freed and still too many pbufs enqueued */
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n",
ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS));
IPFRAG_STATS_INC(ip_frag.memerr);
/* @todo: send ICMP time exceeded here? */
/* drop this pbuf */
goto nullreturn;
}
}
/* Look for the datagram the fragment belongs to in the current datagram queue,
* remembering the previous in the queue for later dequeueing. */
for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) {
/* Check if the incoming fragment matches the one currently present
in the reassembly buffer. If so, we proceed with copying the
fragment into the buffer. */
if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) {
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n",
lwip_ntohs(IPH_ID(fraghdr))));
IPFRAG_STATS_INC(ip_frag.cachehit);
break;
}
}
if (ipr == NULL) {
/* Enqueue a new datagram into the datagram queue */
ipr = ip_reass_enqueue_new_datagram(fraghdr, clen);
/* Bail if unable to enqueue */
if (ipr == NULL) {
goto nullreturn;
}
} else {
if (((lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) &&
((lwip_ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) {
/* ipr->iphdr is not the header from the first fragment, but fraghdr is
* -> copy fraghdr into ipr->iphdr since we want to have the header
* of the first fragment (for ICMP time exceeded and later, for copying
* all options, if supported)*/
SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN);
}
}
/* At this point, we have either created a new entry or pointing
* to an existing one */
/* check for 'no more fragments', and update queue entry*/
is_last = (IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0;
if (is_last) {
u16_t datagram_len = (u16_t)(offset + len);
if ((datagram_len < offset) || (datagram_len > (0xFFFF - IP_HLEN))) {
/* u16_t overflow, cannot handle this */
goto nullreturn_ipr;
}
}
/* find the right place to insert this pbuf */
/* @todo: trim pbufs if fragments are overlapping */
valid = ip_reass_chain_frag_into_datagram_and_validate(ipr, p, is_last);
if (valid == IP_REASS_VALIDATE_PBUF_DROPPED) {
goto nullreturn_ipr;
}
/* if we come here, the pbuf has been enqueued */
/* Track the current number of pbufs current 'in-flight', in order to limit
the number of fragments that may be enqueued at any one time
(overflow checked by testing against IP_REASS_MAX_PBUFS) */
ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount + clen);
if (is_last) {
u16_t datagram_len = (u16_t)(offset + len);
ipr->datagram_len = datagram_len;
ipr->flags |= IP_REASS_FLAG_LASTFRAG;
LWIP_DEBUGF(IP_REASS_DEBUG,
("ip4_reass: last fragment seen, total len %"S16_F"\n",
ipr->datagram_len));
}
if (valid == IP_REASS_VALIDATE_TELEGRAM_FINISHED) {
struct ip_reassdata *ipr_prev;
/* the totally last fragment (flag more fragments = 0) was received at least
* once AND all fragments are received */
u16_t datagram_len = (u16_t)(ipr->datagram_len + IP_HLEN);
/* save the second pbuf before copying the header over the pointer */
r = ((struct ip_reass_helper *)ipr->p->payload)->next_pbuf;
/* copy the original ip header back to the first pbuf */
fraghdr = (struct ip_hdr *)(ipr->p->payload);
SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN);
IPH_LEN_SET(fraghdr, lwip_htons(datagram_len));
IPH_OFFSET_SET(fraghdr, 0);
IPH_CHKSUM_SET(fraghdr, 0);
/* @todo: do we need to set/calculate the correct checksum? */
#if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */
p = ipr->p;
/* chain together the pbufs contained within the reass_data list. */
while (r != NULL) {
iprh = (struct ip_reass_helper *)r->payload;
/* hide the ip header for every succeeding fragment */
pbuf_remove_header(r, IP_HLEN);
pbuf_cat(p, r);
r = iprh->next_pbuf;
}
/* find the previous entry in the linked list */
if (ipr == reassdatagrams) {
ipr_prev = NULL;
} else {
for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) {
if (ipr_prev->next == ipr) {
break;
}
}
}
/* release the sources allocate for the fragment queue entry */
ip_reass_dequeue_datagram(ipr, ipr_prev);
/* and adjust the number of pbufs currently queued for reassembly. */
clen = pbuf_clen(p);
LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= clen);
ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount - clen);
MIB2_STATS_INC(mib2.ipreasmoks);
/* Return the pbuf chain */
return p;
}
/* the datagram is not (yet?) reassembled completely */
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount));
return NULL;
nullreturn_ipr:
LWIP_ASSERT("ipr != NULL", ipr != NULL);
if (ipr->p == NULL) {
/* dropped pbuf after creating a new datagram entry: remove the entry, too */
LWIP_ASSERT("not firstalthough just enqueued", ipr == reassdatagrams);
ip_reass_dequeue_datagram(ipr, NULL);
}
nullreturn:
LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: nullreturn\n"));
IPFRAG_STATS_INC(ip_frag.drop);
pbuf_free(p);
return NULL;
}
#endif /* IP_REASSEMBLY */
#if IP_FRAG
#if !LWIP_NETIF_TX_SINGLE_PBUF
/** Allocate a new struct pbuf_custom_ref */
static struct pbuf_custom_ref *
ip_frag_alloc_pbuf_custom_ref(void)
{
return (struct pbuf_custom_ref *)memp_malloc(MEMP_FRAG_PBUF);
}
/** Free a struct pbuf_custom_ref */
static void
ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref *p)
{
LWIP_ASSERT("p != NULL", p != NULL);
memp_free(MEMP_FRAG_PBUF, p);
}
/** Free-callback function to free a 'struct pbuf_custom_ref', called by
* pbuf_free. */
static void
ipfrag_free_pbuf_custom(struct pbuf *p)
{
struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref *)p;
LWIP_ASSERT("pcr != NULL", pcr != NULL);
LWIP_ASSERT("pcr == p", (void *)pcr == (void *)p);
if (pcr->original != NULL) {
pbuf_free(pcr->original);
}
ip_frag_free_pbuf_custom_ref(pcr);
}
#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */
/**
* Fragment an IP datagram if too large for the netif.
*
* Chop the datagram in MTU sized chunks and send them in order
* by pointing PBUF_REFs into p.
*
* @param p ip packet to send
* @param netif the netif on which to send
* @param dest destination ip address to which to send
*
* @return ERR_OK if sent successfully, err_t otherwise
*/
err_t
ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
{
struct pbuf *rambuf;
#if !LWIP_NETIF_TX_SINGLE_PBUF
struct pbuf *newpbuf;
u16_t newpbuflen = 0;
u16_t left_to_copy;
#endif
struct ip_hdr *original_iphdr;
struct ip_hdr *iphdr;
const u16_t nfb = (u16_t)((netif->mtu - IP_HLEN) / 8);
u16_t left, fragsize;
u16_t ofo;
int last;
u16_t poff = IP_HLEN;
u16_t tmp;
int mf_set;
original_iphdr = (struct ip_hdr *)p->payload;
iphdr = original_iphdr;
if (IPH_HL_BYTES(iphdr) != IP_HLEN) {
/* ip4_frag() does not support IP options */
return ERR_VAL;
}
LWIP_ERROR("ip4_frag(): pbuf too short", p->len >= IP_HLEN, return ERR_VAL);
/* Save original offset */
tmp = lwip_ntohs(IPH_OFFSET(iphdr));
ofo = tmp & IP_OFFMASK;
/* already fragmented? if so, the last fragment we create must have MF, too */
mf_set = tmp & IP_MF;
left = (u16_t)(p->tot_len - IP_HLEN);
while (left) {
/* Fill this fragment */
fragsize = LWIP_MIN(left, (u16_t)(nfb * 8));
#if LWIP_NETIF_TX_SINGLE_PBUF
rambuf = pbuf_alloc(PBUF_IP, fragsize, PBUF_RAM);
if (rambuf == NULL) {
goto memerr;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
(rambuf->len == rambuf->tot_len) && (rambuf->next == NULL));
poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff);
/* make room for the IP header */
if (pbuf_add_header(rambuf, IP_HLEN)) {
pbuf_free(rambuf);
goto memerr;
}
/* fill in the IP header */
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
iphdr = (struct ip_hdr *)rambuf->payload;
#else /* LWIP_NETIF_TX_SINGLE_PBUF */
/* When not using a static buffer, create a chain of pbufs.
* The first will be a PBUF_RAM holding the link and IP header.
* The rest will be PBUF_REFs mirroring the pbuf chain to be fragged,
* but limited to the size of an mtu.
*/
rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM);
if (rambuf == NULL) {
goto memerr;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
(rambuf->len >= (IP_HLEN)));
SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN);
iphdr = (struct ip_hdr *)rambuf->payload;
left_to_copy = fragsize;
while (left_to_copy) {
struct pbuf_custom_ref *pcr;
u16_t plen = (u16_t)(p->len - poff);
LWIP_ASSERT("p->len >= poff", p->len >= poff);
newpbuflen = LWIP_MIN(left_to_copy, plen);
/* Is this pbuf already empty? */
if (!newpbuflen) {
poff = 0;
p = p->next;
continue;
}
pcr = ip_frag_alloc_pbuf_custom_ref();
if (pcr == NULL) {
pbuf_free(rambuf);
goto memerr;
}
/* Mirror this pbuf, although we might not need all of it. */
newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc,
(u8_t *)p->payload + poff, newpbuflen);
if (newpbuf == NULL) {
ip_frag_free_pbuf_custom_ref(pcr);
pbuf_free(rambuf);
goto memerr;
}
pbuf_ref(p);
pcr->original = p;
pcr->pc.custom_free_function = ipfrag_free_pbuf_custom;
/* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain
* so that it is removed when pbuf_dechain is later called on rambuf.
*/
pbuf_cat(rambuf, newpbuf);
left_to_copy = (u16_t)(left_to_copy - newpbuflen);
if (left_to_copy) {
poff = 0;
p = p->next;
}
}
poff = (u16_t)(poff + newpbuflen);
#endif /* LWIP_NETIF_TX_SINGLE_PBUF */
/* Correct header */
last = (left <= netif->mtu - IP_HLEN);
/* Set new offset and MF flag */
tmp = (IP_OFFMASK & (ofo));
if (!last || mf_set) {
/* the last fragment has MF set if the input frame had it */
tmp = tmp | IP_MF;
}
IPH_OFFSET_SET(iphdr, lwip_htons(tmp));
IPH_LEN_SET(iphdr, lwip_htons((u16_t)(fragsize + IP_HLEN)));
IPH_CHKSUM_SET(iphdr, 0);
#if CHECKSUM_GEN_IP
IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN));
}
#endif /* CHECKSUM_GEN_IP */
/* No need for separate header pbuf - we allowed room for it in rambuf
* when allocated.
*/
netif->output(netif, rambuf, dest);
IPFRAG_STATS_INC(ip_frag.xmit);
/* Unfortunately we can't reuse rambuf - the hardware may still be
* using the buffer. Instead we free it (and the ensuing chain) and
* recreate it next time round the loop. If we're lucky the hardware
* will have already sent the packet, the free will really free, and
* there will be zero memory penalty.
*/
pbuf_free(rambuf);
left = (u16_t)(left - fragsize);
ofo = (u16_t)(ofo + nfb);
}
MIB2_STATS_INC(mib2.ipfragoks);
return ERR_OK;
memerr:
MIB2_STATS_INC(mib2.ipfragfails);
return ERR_MEM;
}
#endif /* IP_FRAG */
#endif /* LWIP_IPV4 */
File diff suppressed because it is too large. Load diff
+447
View File
@@ -0,0 +1,447 @@
/**
* @file
* Dynamic pool memory manager
*
* lwIP has dedicated pools for many structures (netconn, protocol control blocks,
* packet buffers, ...). All these pools are managed here.
*
* @defgroup mempool Memory pools
* @ingroup infrastructure
* Custom memory pools
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/memp.h"
#include "lwip/sys.h"
#include "lwip/stats.h"
#include <string.h>
/* Make sure we include everything we need for size calculation required by memp_std.h */
#include "lwip/pbuf.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/altcp.h"
#include "lwip/ip4_frag.h"
#include "lwip/netbuf.h"
#include "lwip/api.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/priv/api_msg.h"
#include "lwip/priv/sockets_priv.h"
#include "lwip/etharp.h"
#include "lwip/igmp.h"
#include "lwip/timeouts.h"
/* needed by default MEMP_NUM_SYS_TIMEOUT */
#include "netif/ppp/ppp_opts.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#include "lwip/priv/nd6_priv.h"
#include "lwip/ip6_frag.h"
#include "lwip/mld6.h"
#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)
#include "lwip/priv/memp_std.h"
const struct memp_desc *const memp_pools[MEMP_MAX] = {
#define LWIP_MEMPOOL(name,num,size,desc) &memp_ ## name,
#include "lwip/priv/memp_std.h"
};
#ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME
#endif
#if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2
#undef MEMP_OVERFLOW_CHECK
/* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */
#define MEMP_OVERFLOW_CHECK 1
#endif
#if MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC
/**
* Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm".
*/
static int
memp_sanity(const struct memp_desc *desc)
{
struct memp *t, *h;
t = *desc->tab;
if (t != NULL) {
for (h = t->next; (t != NULL) && (h != NULL); t = t->next,
h = ((h->next != NULL) ? h->next->next : NULL)) {
if (t == h) {
return 0;
}
}
}
return 1;
}
#endif /* MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC */
#if MEMP_OVERFLOW_CHECK
/**
* Check if a memp element was victim of an overflow or underflow
* (e.g. the restricted area after/before it has been altered)
*
* @param p the memp element to check
* @param desc the pool p comes from
*/
static void
memp_overflow_check_element(struct memp *p, const struct memp_desc *desc)
{
mem_overflow_check_raw((u8_t *)p + MEMP_SIZE, desc->size, "pool ", desc->desc);
}
/**
* Initialize the restricted area of on memp element.
*/
static void
memp_overflow_init_element(struct memp *p, const struct memp_desc *desc)
{
mem_overflow_init_raw((u8_t *)p + MEMP_SIZE, desc->size);
}
#if MEMP_OVERFLOW_CHECK >= 2
/**
* Do an overflow check for all elements in every pool.
*
* @see memp_overflow_check_element for a description of the check
*/
static void
memp_overflow_check_all(void)
{
u16_t i, j;
struct memp *p;
SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
for (i = 0; i < MEMP_MAX; ++i) {
p = (struct memp *)LWIP_MEM_ALIGN(memp_pools[i]->base);
for (j = 0; j < memp_pools[i]->num; ++j) {
memp_overflow_check_element(p, memp_pools[i]);
p = LWIP_ALIGNMENT_CAST(struct memp *, ((u8_t *)p + MEMP_SIZE + memp_pools[i]->size + MEM_SANITY_REGION_AFTER_ALIGNED));
}
}
SYS_ARCH_UNPROTECT(old_level);
}
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
#endif /* MEMP_OVERFLOW_CHECK */
/**
* Initialize custom memory pool.
* Related functions: memp_malloc_pool, memp_free_pool
*
* @param desc pool to initialize
*/
void
memp_init_pool(const struct memp_desc *desc)
{
#if MEMP_MEM_MALLOC
LWIP_UNUSED_ARG(desc);
#else
int i;
struct memp *memp;
*desc->tab = NULL;
memp = (struct memp *)LWIP_MEM_ALIGN(desc->base);
#if MEMP_MEM_INIT
/* force memset on pool memory */
memset(memp, 0, (size_t)desc->num * (MEMP_SIZE + desc->size
#if MEMP_OVERFLOW_CHECK
+ MEM_SANITY_REGION_AFTER_ALIGNED
#endif
));
#endif
/* create a linked list of memp elements */
for (i = 0; i < desc->num; ++i) {
memp->next = *desc->tab;
*desc->tab = memp;
#if MEMP_OVERFLOW_CHECK
memp_overflow_init_element(memp, desc);
#endif /* MEMP_OVERFLOW_CHECK */
/* cast through void* to get rid of alignment warnings */
memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + desc->size
#if MEMP_OVERFLOW_CHECK
+ MEM_SANITY_REGION_AFTER_ALIGNED
#endif
);
}
#if MEMP_STATS
desc->stats->avail = desc->num;
#endif /* MEMP_STATS */
#endif /* !MEMP_MEM_MALLOC */
#if MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY)
desc->stats->name = desc->desc;
#endif /* MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY) */
}
/**
* Initializes lwIP built-in pools.
* Related functions: memp_malloc, memp_free
*
* Carves out memp_memory into linked lists for each pool-type.
*/
void
memp_init(void)
{
u16_t i;
/* for every pool: */
for (i = 0; i < LWIP_ARRAYSIZE(memp_pools); i++) {
memp_init_pool(memp_pools[i]);
#if LWIP_STATS && MEMP_STATS
lwip_stats.memp[i] = memp_pools[i]->stats;
#endif
}
#if MEMP_OVERFLOW_CHECK >= 2
/* check everything a first time to see if it worked */
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
}
static void *
#if !MEMP_OVERFLOW_CHECK
do_memp_malloc_pool(const struct memp_desc *desc)
#else
do_memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int line)
#endif
{
struct memp *memp;
SYS_ARCH_DECL_PROTECT(old_level);
#if MEMP_MEM_MALLOC
memp = (struct memp *)mem_malloc(MEMP_SIZE + MEMP_ALIGN_SIZE(desc->size));
SYS_ARCH_PROTECT(old_level);
#else /* MEMP_MEM_MALLOC */
SYS_ARCH_PROTECT(old_level);
memp = *desc->tab;
#endif /* MEMP_MEM_MALLOC */
if (memp != NULL) {
#if !MEMP_MEM_MALLOC
#if MEMP_OVERFLOW_CHECK == 1
memp_overflow_check_element(memp, desc);
#endif /* MEMP_OVERFLOW_CHECK */
*desc->tab = memp->next;
#if MEMP_OVERFLOW_CHECK
memp->next = NULL;
#endif /* MEMP_OVERFLOW_CHECK */
#endif /* !MEMP_MEM_MALLOC */
#if MEMP_OVERFLOW_CHECK
memp->file = file;
memp->line = line;
#if MEMP_MEM_MALLOC
memp_overflow_init_element(memp, desc);
#endif /* MEMP_MEM_MALLOC */
#endif /* MEMP_OVERFLOW_CHECK */
LWIP_ASSERT("memp_malloc: memp properly aligned",
((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
#if MEMP_STATS
desc->stats->used++;
if (desc->stats->used > desc->stats->max) {
desc->stats->max = desc->stats->used;
}
#endif
SYS_ARCH_UNPROTECT(old_level);
/* cast through u8_t* to get rid of alignment warnings */
return ((u8_t *)memp + MEMP_SIZE);
} else {
#if MEMP_STATS
desc->stats->err++;
#endif
SYS_ARCH_UNPROTECT(old_level);
LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", desc->desc));
}
return NULL;
}
/**
* Get an element from a custom pool.
*
* @param desc the pool to get an element from
*
* @return a pointer to the allocated memory or a NULL pointer on error
*/
void *
#if !MEMP_OVERFLOW_CHECK
memp_malloc_pool(const struct memp_desc *desc)
#else
memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int line)
#endif
{
LWIP_ASSERT("invalid pool desc", desc != NULL);
if (desc == NULL) {
return NULL;
}
#if !MEMP_OVERFLOW_CHECK
return do_memp_malloc_pool(desc);
#else
return do_memp_malloc_pool_fn(desc, file, line);
#endif
}
/**
* Get an element from a specific pool.
*
* @param type the pool to get an element from
*
* @return a pointer to the allocated memory or a NULL pointer on error
*/
void *
#if !MEMP_OVERFLOW_CHECK
memp_malloc(memp_t type)
#else
memp_malloc_fn(memp_t type, const char *file, const int line)
#endif
{
void *memp;
LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
#if MEMP_OVERFLOW_CHECK >= 2
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
#if !MEMP_OVERFLOW_CHECK
memp = do_memp_malloc_pool(memp_pools[type]);
#else
memp = do_memp_malloc_pool_fn(memp_pools[type], file, line);
#endif
return memp;
}
static void
do_memp_free_pool(const struct memp_desc *desc, void *mem)
{
struct memp *memp;
SYS_ARCH_DECL_PROTECT(old_level);
LWIP_ASSERT("memp_free: mem properly aligned",
((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
/* cast through void* to get rid of alignment warnings */
memp = (struct memp *)(void *)((u8_t *)mem - MEMP_SIZE);
SYS_ARCH_PROTECT(old_level);
#if MEMP_OVERFLOW_CHECK == 1
memp_overflow_check_element(memp, desc);
#endif /* MEMP_OVERFLOW_CHECK */
#if MEMP_STATS
desc->stats->used--;
#endif
#if MEMP_MEM_MALLOC
LWIP_UNUSED_ARG(desc);
SYS_ARCH_UNPROTECT(old_level);
mem_free(memp);
#else /* MEMP_MEM_MALLOC */
memp->next = *desc->tab;
*desc->tab = memp;
#if MEMP_SANITY_CHECK
LWIP_ASSERT("memp sanity", memp_sanity(desc));
#endif /* MEMP_SANITY_CHECK */
SYS_ARCH_UNPROTECT(old_level);
#endif /* !MEMP_MEM_MALLOC */
}
/**
* Put a custom pool element back into its pool.
*
* @param desc the pool where to put mem
* @param mem the memp element to free
*/
void
memp_free_pool(const struct memp_desc *desc, void *mem)
{
LWIP_ASSERT("invalid pool desc", desc != NULL);
if ((desc == NULL) || (mem == NULL)) {
return;
}
do_memp_free_pool(desc, mem);
}
/**
* Put an element back into its pool.
*
* @param type the pool where to put mem
* @param mem the memp element to free
*/
void
memp_free(memp_t type, void *mem)
{
#ifdef LWIP_HOOK_MEMP_AVAILABLE
struct memp *old_first;
#endif
LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;);
if (mem == NULL) {
return;
}
#if MEMP_OVERFLOW_CHECK >= 2
memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
#ifdef LWIP_HOOK_MEMP_AVAILABLE
old_first = *memp_pools[type]->tab;
#endif
do_memp_free_pool(memp_pools[type], mem);
#ifdef LWIP_HOOK_MEMP_AVAILABLE
if (old_first == NULL) {
LWIP_HOOK_MEMP_AVAILABLE(type);
}
#endif
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+671
View File
@@ -0,0 +1,671 @@
/**
* @file
* Implementation of raw protocol PCBs for low-level handling of
* different types of protocols besides (or overriding) those
* already available in lwIP.\n
* See also @ref raw_raw
*
* @defgroup raw_raw RAW
* @ingroup callbackstyle_api
* Implementation of raw protocol PCBs for low-level handling of
* different types of protocols besides (or overriding) those
* already available in lwIP.\n
* @see @ref api
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/memp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/raw.h"
#include "lwip/priv/raw_priv.h"
#include "lwip/stats.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/inet_chksum.h"
#include <string.h>
/** The list of RAW PCBs */
static struct raw_pcb *raw_pcbs;
static u8_t
raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast)
{
LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */
/* check if PCB is bound to specific netif */
if ((pcb->netif_idx != NETIF_NO_INDEX) &&
(pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) {
return 0;
}
#if LWIP_IPV4 && LWIP_IPV6
/* Dual-stack: PCBs listening to any IP type also listen to any IP address */
if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
#if IP_SOF_BROADCAST_RECV
if ((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) {
return 0;
}
#endif /* IP_SOF_BROADCAST_RECV */
return 1;
}
#endif /* LWIP_IPV4 && LWIP_IPV6 */
/* Only need to check PCB if incoming IP version matches PCB IP version */
if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) {
#if LWIP_IPV4
/* Special case: IPv4 broadcast: receive all broadcasts
* Note: broadcast variable can only be 1 if it is an IPv4 broadcast */
if (broadcast != 0) {
#if IP_SOF_BROADCAST_RECV
if (ip_get_option(pcb, SOF_BROADCAST))
#endif /* IP_SOF_BROADCAST_RECV */
{
if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip))) {
return 1;
}
}
} else
#endif /* LWIP_IPV4 */
/* Handle IPv4 and IPv6: catch all or exact match */
if (ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) {
return 1;
}
}
return 0;
}
/**
* Determine if in incoming IP packet is covered by a RAW PCB
* and if so, pass it to a user-provided receive callback function.
*
* Given an incoming IP datagram (as a chain of pbufs) this function
* finds a corresponding RAW PCB and calls the corresponding receive
* callback function.
*
* @param p pbuf to be demultiplexed to a RAW PCB.
* @param inp network interface on which the datagram was received.
* @return - 1 if the packet has been eaten by a RAW PCB receive
* callback function. The caller MAY NOT not reference the
* packet any longer, and MAY NOT call pbuf_free().
* @return - 0 if packet is not eaten (pbuf is still referenced by the
* caller).
*
*/
raw_input_state_t
raw_input(struct pbuf *p, struct netif *inp)
{
struct raw_pcb *pcb, *prev;
s16_t proto;
raw_input_state_t ret = RAW_INPUT_NONE;
u8_t broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif());
LWIP_UNUSED_ARG(inp);
#if LWIP_IPV6
#if LWIP_IPV4
if (IP_HDR_GET_VERSION(p->payload) == 6)
#endif /* LWIP_IPV4 */
{
struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload;
proto = IP6H_NEXTH(ip6hdr);
}
#if LWIP_IPV4
else
#endif /* LWIP_IPV4 */
#endif /* LWIP_IPV6 */
#if LWIP_IPV4
{
proto = IPH_PROTO((struct ip_hdr *)p->payload);
}
#endif /* LWIP_IPV4 */
prev = NULL;
pcb = raw_pcbs;
/* loop through all raw pcbs until the packet is eaten by one */
/* this allows multiple pcbs to match against the packet by design */
while (pcb != NULL) {
if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) &&
(((pcb->flags & RAW_FLAGS_CONNECTED) == 0) ||
ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) {
/* receive callback function available? */
if (pcb->recv != NULL) {
u8_t eaten;
#ifndef LWIP_NOASSERT
void *old_payload = p->payload;
#endif
ret = RAW_INPUT_DELIVERED;
/* the receive callback function did not eat the packet? */
eaten = pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr());
if (eaten != 0) {
/* receive function ate the packet */
p = NULL;
if (prev != NULL) {
/* move the pcb to the front of raw_pcbs so that is
found faster next time */
prev->next = pcb->next;
pcb->next = raw_pcbs;
raw_pcbs = pcb;
}
return RAW_INPUT_EATEN;
} else {
/* sanity-check that the receive callback did not alter the pbuf */
LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet",
p->payload == old_payload);
}
}
/* no receive callback function was set for this raw PCB */
}
/* drop the packet */
prev = pcb;
pcb = pcb->next;
}
return ret;
}
/**
* @ingroup raw_raw
* Bind a RAW PCB.
*
* @param pcb RAW PCB to be bound with a local address ipaddr.
* @param ipaddr local IP address to bind with. Use IP4_ADDR_ANY to
* bind to all local interfaces.
*
* @return lwIP error code.
* - ERR_OK. Successful. No error occurred.
* - ERR_USE. The specified IP address is already bound to by
* another RAW PCB.
*
* @see raw_disconnect()
*/
err_t
raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
{
LWIP_ASSERT_CORE_LOCKED();
if ((pcb == NULL) || (ipaddr == NULL)) {
return ERR_VAL;
}
ip_addr_set_ipaddr(&pcb->local_ip, ipaddr);
#if LWIP_IPV6 && LWIP_IPV6_SCOPES
/* If the given IP address should have a zone but doesn't, assign one now.
* This is legacy support: scope-aware callers should always provide properly
* zoned source addresses. */
if (IP_IS_V6(&pcb->local_ip) &&
ip6_addr_lacks_zone(ip_2_ip6(&pcb->local_ip), IP6_UNKNOWN)) {
ip6_addr_select_zone(ip_2_ip6(&pcb->local_ip), ip_2_ip6(&pcb->local_ip));
}
#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
return ERR_OK;
}
/**
* @ingroup raw_raw
* Bind an RAW PCB to a specific netif.
* After calling this function, all packets received via this PCB
* are guaranteed to have come in via the specified netif, and all
* outgoing packets will go out via the specified netif.
*
* @param pcb RAW PCB to be bound with netif.
* @param netif netif to bind to. Can be NULL.
*
* @see raw_disconnect()
*/
void
raw_bind_netif(struct raw_pcb *pcb, const struct netif *netif)
{
LWIP_ASSERT_CORE_LOCKED();
if (netif != NULL) {
pcb->netif_idx = netif_get_index(netif);
} else {
pcb->netif_idx = NETIF_NO_INDEX;
}
}
/**
* @ingroup raw_raw
* Connect an RAW PCB. This function is required by upper layers
* of lwip. Using the raw api you could use raw_sendto() instead
*
* This will associate the RAW PCB with the remote address.
*
* @param pcb RAW PCB to be connected with remote address ipaddr and port.
* @param ipaddr remote IP address to connect with.
*
* @return lwIP error code
*
* @see raw_disconnect() and raw_sendto()
*/
err_t
raw_connect(struct raw_pcb *pcb, const ip_addr_t *ipaddr)
{
LWIP_ASSERT_CORE_LOCKED();
if ((pcb == NULL) || (ipaddr == NULL)) {
return ERR_VAL;
}
ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr);
#if LWIP_IPV6 && LWIP_IPV6_SCOPES
/* If the given IP address should have a zone but doesn't, assign one now,
* using the bound address to make a more informed decision when possible. */
if (IP_IS_V6(&pcb->remote_ip) &&
ip6_addr_lacks_zone(ip_2_ip6(&pcb->remote_ip), IP6_UNKNOWN)) {
ip6_addr_select_zone(ip_2_ip6(&pcb->remote_ip), ip_2_ip6(&pcb->local_ip));
}
#endif /* LWIP_IPV6 && LWIP_IPV6_SCOPES */
raw_set_flags(pcb, RAW_FLAGS_CONNECTED);
return ERR_OK;
}
/**
* @ingroup raw_raw
* Disconnect a RAW PCB.
*
* @param pcb the raw pcb to disconnect.
*/
void
raw_disconnect(struct raw_pcb *pcb)
{
LWIP_ASSERT_CORE_LOCKED();
/* reset remote address association */
#if LWIP_IPV4 && LWIP_IPV6
if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {
ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE);
} else {
#endif
ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip);
#if LWIP_IPV4 && LWIP_IPV6
}
#endif
pcb->netif_idx = NETIF_NO_INDEX;
/* mark PCB as unconnected */
raw_clear_flags(pcb, RAW_FLAGS_CONNECTED);
}
/**
* @ingroup raw_raw
* Set the callback function for received packets that match the
* raw PCB's protocol and binding.
*
* The callback function MUST either
* - eat the packet by calling pbuf_free() and returning non-zero. The
* packet will not be passed to other raw PCBs or other protocol layers.
* - not free the packet, and return zero. The packet will be matched
* against further PCBs and/or forwarded to another protocol layers.
*/
void
raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg)
{
LWIP_ASSERT_CORE_LOCKED();
/* remember recv() callback and user data */
pcb->recv = recv;
pcb->recv_arg = recv_arg;
}
/**
* @ingroup raw_raw
* Send the raw IP packet to the given address. An IP header will be prepended
* to the packet, unless the RAW_FLAGS_HDRINCL flag is set on the PCB. In that
* case, the packet must include an IP header, which will then be sent as is.
*
* @param pcb the raw pcb which to send
* @param p the IP payload to send
* @param ipaddr the destination address of the IP packet
*
*/
err_t
raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
{
struct netif *netif;
const ip_addr_t *src_ip;
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
return ERR_VAL;
}
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
if (pcb->netif_idx != NETIF_NO_INDEX) {
netif = netif_get_by_index(pcb->netif_idx);
} else {
#if LWIP_MULTICAST_TX_OPTIONS
netif = NULL;
if (ip_addr_ismulticast(ipaddr)) {
/* For multicast-destined packets, use the user-provided interface index to
* determine the outgoing interface, if an interface index is set and a
* matching netif can be found. Otherwise, fall back to regular routing. */
netif = netif_get_by_index(pcb->mcast_ifindex);
}
if (netif == NULL)
#endif /* LWIP_MULTICAST_TX_OPTIONS */
{
netif = ip_route(&pcb->local_ip, ipaddr);
}
}
if (netif == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ipaddr);
return ERR_RTE;
}
if (ip_addr_isany(&pcb->local_ip) || ip_addr_ismulticast(&pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
src_ip = ip_netif_get_local_ip(netif, ipaddr);
#if LWIP_IPV6
if (src_ip == NULL) {
return ERR_RTE;
}
#endif /* LWIP_IPV6 */
} else {
/* use RAW PCB local IP address as source address */
src_ip = &pcb->local_ip;
}
return raw_sendto_if_src(pcb, p, ipaddr, netif, src_ip);
}
/**
* @ingroup raw_raw
* Send the raw IP packet to the given address, using a particular outgoing
* netif and source IP address. An IP header will be prepended to the packet,
* unless the RAW_FLAGS_HDRINCL flag is set on the PCB. In that case, the
* packet must include an IP header, which will then be sent as is.
*
* @param pcb RAW PCB used to send the data
* @param p chain of pbufs to be sent
* @param dst_ip destination IP address
* @param netif the netif used for sending
* @param src_ip source IP address
*/
err_t
raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip,
struct netif *netif, const ip_addr_t *src_ip)
{
err_t err;
struct pbuf *q; /* q will be sent down the stack */
u16_t header_size;
u8_t ttl;
LWIP_ASSERT_CORE_LOCKED();
if ((pcb == NULL) || (dst_ip == NULL) || (netif == NULL) || (src_ip == NULL) ||
!IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) {
return ERR_VAL;
}
header_size = (
#if LWIP_IPV4 && LWIP_IPV6
IP_IS_V6(dst_ip) ? IP6_HLEN : IP_HLEN);
#elif LWIP_IPV4
IP_HLEN);
#else
IP6_HLEN);
#endif
/* Handle the HDRINCL option as an exception: none of the code below applies
* to this case, and sending the packet needs to be done differently too. */
if (pcb->flags & RAW_FLAGS_HDRINCL) {
/* A full header *must* be present in the first pbuf of the chain, as the
* output routines may access its fields directly. */
if (p->len < header_size) {
return ERR_VAL;
}
/* @todo multicast loop support, if at all desired for this scenario.. */
NETIF_SET_HINTS(netif, &pcb->netif_hints);
err = ip_output_if_hdrincl(p, src_ip, dst_ip, netif);
NETIF_RESET_HINTS(netif);
return err;
}
/* packet too large to add an IP header without causing an overflow? */
if ((u16_t)(p->tot_len + header_size) < p->tot_len) {
return ERR_MEM;
}
/* not enough space to add an IP header to first pbuf in given p chain? */
if (pbuf_add_header(p, header_size)) {
/* allocate header in new pbuf */
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
return ERR_MEM;
}
if (p->tot_len != 0) {
/* chain header q in front of given pbuf p */
pbuf_chain(q, p);
}
/* { first pbuf q points to header pbuf } */
LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
} else {
/* first pbuf q equals given pbuf */
q = p;
if (pbuf_remove_header(q, header_size)) {
LWIP_ASSERT("Can't restore header we just removed!", 0);
return ERR_MEM;
}
}
#if IP_SOF_BROADCAST
if (IP_IS_V4(dst_ip)) {
/* broadcast filter? */
if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(dst_ip, netif)) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_VAL;
}
}
#endif /* IP_SOF_BROADCAST */
/* Multicast Loop? */
#if LWIP_MULTICAST_TX_OPTIONS
if (((pcb->flags & RAW_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) {
q->flags |= PBUF_FLAG_MCASTLOOP;
}
#endif /* LWIP_MULTICAST_TX_OPTIONS */
#if LWIP_IPV6
/* If requested, based on the IPV6_CHECKSUM socket option per RFC3542,
compute the checksum and update the checksum in the payload. */
if (IP_IS_V6(dst_ip) && pcb->chksum_reqd) {
u16_t chksum = ip6_chksum_pseudo(p, pcb->protocol, p->tot_len, ip_2_ip6(src_ip), ip_2_ip6(dst_ip));
LWIP_ASSERT("Checksum must fit into first pbuf", p->len >= (pcb->chksum_offset + 2));
SMEMCPY(((u8_t *)p->payload) + pcb->chksum_offset, &chksum, sizeof(u16_t));
}
#endif
/* Determine TTL to use */
#if LWIP_MULTICAST_TX_OPTIONS
ttl = (ip_addr_ismulticast(dst_ip) ? raw_get_multicast_ttl(pcb) : pcb->ttl);
#else /* LWIP_MULTICAST_TX_OPTIONS */
ttl = pcb->ttl;
#endif /* LWIP_MULTICAST_TX_OPTIONS */
NETIF_SET_HINTS(netif, &pcb->netif_hints);
err = ip_output_if(q, src_ip, dst_ip, ttl, pcb->tos, pcb->protocol, netif);
NETIF_RESET_HINTS(netif);
/* did we chain a header earlier? */
if (q != p) {
/* free the header */
pbuf_free(q);
}
return err;
}
/**
* @ingroup raw_raw
* Send the raw IP packet to the address given by raw_connect()
*
* @param pcb the raw pcb which to send
* @param p the IP payload to send
*
*/
err_t
raw_send(struct raw_pcb *pcb, struct pbuf *p)
{
return raw_sendto(pcb, p, &pcb->remote_ip);
}
/**
* @ingroup raw_raw
* Remove an RAW PCB.
*
* @param pcb RAW PCB to be removed. The PCB is removed from the list of
* RAW PCB's and the data structure is freed from memory.
*
* @see raw_new()
*/
void
raw_remove(struct raw_pcb *pcb)
{
struct raw_pcb *pcb2;
LWIP_ASSERT_CORE_LOCKED();
/* pcb to be removed is first in list? */
if (raw_pcbs == pcb) {
/* make list start at 2nd pcb */
raw_pcbs = raw_pcbs->next;
/* pcb not 1st in list */
} else {
for (pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {
/* find pcb in raw_pcbs list */
if (pcb2->next != NULL && pcb2->next == pcb) {
/* remove pcb from list */
pcb2->next = pcb->next;
break;
}
}
}
memp_free(MEMP_RAW_PCB, pcb);
}
/**
* @ingroup raw_raw
* Create a RAW PCB.
*
* @return The RAW PCB which was created. NULL if the PCB data structure
* could not be allocated.
*
* @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP)
*
* @see raw_remove()
*/
struct raw_pcb *
raw_new(u8_t proto)
{
struct raw_pcb *pcb;
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n"));
LWIP_ASSERT_CORE_LOCKED();
pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB);
/* could allocate RAW PCB? */
if (pcb != NULL) {
/* initialize PCB to all zeroes */
memset(pcb, 0, sizeof(struct raw_pcb));
pcb->protocol = proto;
pcb->ttl = RAW_TTL;
#if LWIP_MULTICAST_TX_OPTIONS
raw_set_multicast_ttl(pcb, RAW_TTL);
#endif /* LWIP_MULTICAST_TX_OPTIONS */
pcb->next = raw_pcbs;
raw_pcbs = pcb;
}
return pcb;
}
/**
* @ingroup raw_raw
* Create a RAW PCB for specific IP type.
*
* @return The RAW PCB which was created. NULL if the PCB data structure
* could not be allocated.
*
* @param type IP address type, see @ref lwip_ip_addr_type definitions.
* If you want to listen to IPv4 and IPv6 (dual-stack) packets,
* supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE.
* @param proto the protocol number (next header) of the IPv6 packet payload
* (e.g. IP6_NEXTH_ICMP6)
*
* @see raw_remove()
*/
struct raw_pcb *
raw_new_ip_type(u8_t type, u8_t proto)
{
struct raw_pcb *pcb;
LWIP_ASSERT_CORE_LOCKED();
pcb = raw_new(proto);
#if LWIP_IPV4 && LWIP_IPV6
if (pcb != NULL) {
IP_SET_TYPE_VAL(pcb->local_ip, type);
IP_SET_TYPE_VAL(pcb->remote_ip, type);
}
#else /* LWIP_IPV4 && LWIP_IPV6 */
LWIP_UNUSED_ARG(type);
#endif /* LWIP_IPV4 && LWIP_IPV6 */
return pcb;
}
/** This function is called from netif.c when address is changed
*
* @param old_addr IP address of the netif before change
* @param new_addr IP address of the netif after change
*/
void raw_netif_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr)
{
struct raw_pcb *rpcb;
if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) {
for (rpcb = raw_pcbs; rpcb != NULL; rpcb = rpcb->next) {
/* PCB bound to current local interface address? */
if (ip_addr_cmp(&rpcb->local_ip, old_addr)) {
/* The PCB is bound to the old ipaddr and
* is set to bound to the new one instead */
ip_addr_copy(rpcb->local_ip, *new_addr);
}
}
}
}
#endif /* LWIP_RAW */
+169
View File
@@ -0,0 +1,169 @@
/**
* @file
* Statistics module
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */
#include "lwip/def.h"
#include "lwip/stats.h"
#include "lwip/mem.h"
#include "lwip/debug.h"
#include <string.h>
struct stats_ lwip_stats;
void
stats_init(void)
{
#ifdef LWIP_DEBUG
#if MEM_STATS
lwip_stats.mem.name = "MEM";
#endif /* MEM_STATS */
#endif /* LWIP_DEBUG */
}
#if LWIP_STATS_DISPLAY
void
stats_display_proto(struct stats_proto *proto, const char *name)
{
LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit));
LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv));
LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw));
LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop));
LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr));
LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr));
LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr));
LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr));
LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr));
LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr));
LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err));
LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit));
}
#if IGMP_STATS || MLD6_STATS
void
stats_display_igmp(struct stats_igmp *igmp, const char *name)
{
LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit));
LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv));
LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop));
LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr));
LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr));
LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr));
LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr));
LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1));
LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n\t", igmp->rx_group));
LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n\t", igmp->rx_general));
LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report));
LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join));
LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave));
LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n", igmp->tx_report));
}
#endif /* IGMP_STATS || MLD6_STATS */
#if MEM_STATS || MEMP_STATS
void
stats_display_mem(struct stats_mem *mem, const char *name)
{
LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name));
LWIP_PLATFORM_DIAG(("avail: %"MEM_SIZE_F"\n\t", mem->avail));
LWIP_PLATFORM_DIAG(("used: %"MEM_SIZE_F"\n\t", mem->used));
LWIP_PLATFORM_DIAG(("max: %"MEM_SIZE_F"\n\t", mem->max));
LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n", mem->err));
}
#if MEMP_STATS
void
stats_display_memp(struct stats_mem *mem, int idx)
{
if (idx < MEMP_MAX) {
stats_display_mem(mem, mem->name);
}
}
#endif /* MEMP_STATS */
#endif /* MEM_STATS || MEMP_STATS */
#if SYS_STATS
void
stats_display_sys(struct stats_sys *sys)
{
LWIP_PLATFORM_DIAG(("\nSYS\n\t"));
LWIP_PLATFORM_DIAG(("sem.used: %"STAT_COUNTER_F"\n\t", sys->sem.used));
LWIP_PLATFORM_DIAG(("sem.max: %"STAT_COUNTER_F"\n\t", sys->sem.max));
LWIP_PLATFORM_DIAG(("sem.err: %"STAT_COUNTER_F"\n\t", sys->sem.err));
LWIP_PLATFORM_DIAG(("mutex.used: %"STAT_COUNTER_F"\n\t", sys->mutex.used));
LWIP_PLATFORM_DIAG(("mutex.max: %"STAT_COUNTER_F"\n\t", sys->mutex.max));
LWIP_PLATFORM_DIAG(("mutex.err: %"STAT_COUNTER_F"\n\t", sys->mutex.err));
LWIP_PLATFORM_DIAG(("mbox.used: %"STAT_COUNTER_F"\n\t", sys->mbox.used));
LWIP_PLATFORM_DIAG(("mbox.max: %"STAT_COUNTER_F"\n\t", sys->mbox.max));
LWIP_PLATFORM_DIAG(("mbox.err: %"STAT_COUNTER_F"\n", sys->mbox.err));
}
#endif /* SYS_STATS */
void
stats_display(void)
{
s16_t i;
LINK_STATS_DISPLAY();
ETHARP_STATS_DISPLAY();
IPFRAG_STATS_DISPLAY();
IP6_FRAG_STATS_DISPLAY();
IP_STATS_DISPLAY();
ND6_STATS_DISPLAY();
IP6_STATS_DISPLAY();
IGMP_STATS_DISPLAY();
MLD6_STATS_DISPLAY();
ICMP_STATS_DISPLAY();
ICMP6_STATS_DISPLAY();
UDP_STATS_DISPLAY();
TCP_STATS_DISPLAY();
MEM_STATS_DISPLAY();
for (i = 0; i < MEMP_MAX; i++) {
MEMP_STATS_DISPLAY(i);
}
SYS_STATS_DISPLAY();
}
#endif /* LWIP_STATS_DISPLAY */
#endif /* LWIP_STATS */
+148
View File
@@ -0,0 +1,148 @@
/**
* @file
* lwIP Operating System abstraction
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/**
* @defgroup sys_layer Porting (system abstraction layer)
* @ingroup lwip
*
* @defgroup sys_os OS abstraction layer
* @ingroup sys_layer
* No need to implement functions in this section in NO_SYS mode.
* The OS-specific code should be implemented in arch/sys_arch.h
* and sys_arch.c of your port.
*
* The operating system emulation layer provides a common interface
* between the lwIP code and the underlying operating system kernel. The
* general idea is that porting lwIP to new architectures requires only
* small changes to a few header files and a new sys_arch
* implementation. It is also possible to do a sys_arch implementation
* that does not rely on any underlying operating system.
*
* The sys_arch provides semaphores, mailboxes and mutexes to lwIP. For the full
* lwIP functionality, multiple threads support can be implemented in the
* sys_arch, but this is not required for the basic lwIP
* functionality. Timer scheduling is implemented in lwIP, but can be implemented
* by the sys_arch port (LWIP_TIMERS_CUSTOM==1).
*
* In addition to the source file providing the functionality of sys_arch,
* the OS emulation layer must provide several header files defining
* macros used throughout lwip. The files required and the macros they
* must define are listed below the sys_arch description.
*
* Since lwIP 1.4.0, semaphore, mutexes and mailbox functions are prototyped in a way that
* allows both using pointers or actual OS structures to be used. This way, memory
* required for such types can be either allocated in place (globally or on the
* stack) or on the heap (allocated internally in the "*_new()" functions).
*
* Note:
* -----
* Be careful with using mem_malloc() in sys_arch. When malloc() refers to
* mem_malloc() you can run into a circular function call problem. In mem.c
* mem_init() tries to allocate a semaphore using mem_malloc, which of course
* can't be performed when sys_arch uses mem_malloc.
*
* @defgroup sys_sem Semaphores
* @ingroup sys_os
* Semaphores can be either counting or binary - lwIP works with both
* kinds.
* Semaphores are represented by the type "sys_sem_t" which is typedef'd
* in the sys_arch.h file. Mailboxes are equivalently represented by the
* type "sys_mbox_t". Mutexes are represented by the type "sys_mutex_t".
* lwIP does not place any restrictions on how these types are represented
* internally.
*
* @defgroup sys_mutex Mutexes
* @ingroup sys_os
* Mutexes are recommended to correctly handle priority inversion,
* especially if you use LWIP_CORE_LOCKING .
*
* @defgroup sys_mbox Mailboxes
* @ingroup sys_os
* Mailboxes should be implemented as a queue which allows multiple messages
* to be posted (implementing as a rendez-vous point where only one message can be
* posted at a time can have a highly negative impact on performance). A message
* in a mailbox is just a pointer, nothing more.
*
* @defgroup sys_time Time
* @ingroup sys_layer
*
* @defgroup sys_prot Critical sections
* @ingroup sys_layer
* Used to protect short regions of code against concurrent access.
* - Your system is a bare-metal system (probably with an RTOS)
* and interrupts are under your control:
* Implement this as LockInterrupts() / UnlockInterrupts()
* - Your system uses an RTOS with deferred interrupt handling from a
* worker thread: Implement as a global mutex or lock/unlock scheduler
* - Your system uses a high-level OS with e.g. POSIX signals:
* Implement as a global mutex
*
* @defgroup sys_misc Misc
* @ingroup sys_os
*/
#include "lwip/opt.h"
#include "lwip/sys.h"
/* Most of the functions defined in sys.h must be implemented in the
* architecture-dependent file sys_arch.c */
#if !NO_SYS
#ifndef sys_msleep
/**
* Sleep for some ms. Timeouts are NOT processed while sleeping.
*
* @param ms number of milliseconds to sleep
*/
void
sys_msleep(u32_t ms)
{
if (ms > 0) {
sys_sem_t delaysem;
err_t err = sys_sem_new(&delaysem, 0);
if (err == ERR_OK) {
sys_arch_sem_wait(&delaysem, ms);
sys_sem_free(&delaysem);
}
}
}
#endif /* sys_msleep */
#endif /* !NO_SYS */
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,451 @@
/**
* @file
* Stack-internal timers implementation.
* This file includes timer callbacks for stack-internal timers as well as
* functions to set up or stop timers and check for expired timers.
*
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
* Simon Goldschmidt
*
*/
#include "lwip/opt.h"
#include "lwip/timeouts.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/def.h"
#include "lwip/memp.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/ip4_frag.h"
#include "lwip/etharp.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/igmp.h"
#include "lwip/dns.h"
#include "lwip/nd6.h"
#include "lwip/ip6_frag.h"
#include "lwip/mld6.h"
#include "lwip/dhcp6.h"
#include "lwip/sys.h"
#include "lwip/pbuf.h"
#if LWIP_DEBUG_TIMERNAMES
#define HANDLER(x) x, #x
#else /* LWIP_DEBUG_TIMERNAMES */
#define HANDLER(x) x
#endif /* LWIP_DEBUG_TIMERNAMES */
#define LWIP_MAX_TIMEOUT 0x7fffffff
/* Check if timer's expiry time is greater than time and care about u32_t wraparounds */
#define TIME_LESS_THAN(t, compare_to) ( (((u32_t)((t)-(compare_to))) > LWIP_MAX_TIMEOUT) ? 1 : 0 )
/** This array contains all stack-internal cyclic timers. To get the number of
* timers, use LWIP_ARRAYSIZE() */
const struct lwip_cyclic_timer lwip_cyclic_timers[] = {
#if LWIP_TCP
/* The TCP timer is a special case: it does not have to run always and
is triggered to start from TCP using tcp_timer_needed() */
{TCP_TMR_INTERVAL, HANDLER(tcp_tmr)},
#endif /* LWIP_TCP */
#if LWIP_IPV4
#if IP_REASSEMBLY
{IP_TMR_INTERVAL, HANDLER(ip_reass_tmr)},
#endif /* IP_REASSEMBLY */
#if LWIP_ARP
{ARP_TMR_INTERVAL, HANDLER(etharp_tmr)},
#endif /* LWIP_ARP */
#if LWIP_DHCP
{DHCP_COARSE_TIMER_MSECS, HANDLER(dhcp_coarse_tmr)},
{DHCP_FINE_TIMER_MSECS, HANDLER(dhcp_fine_tmr)},
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
{AUTOIP_TMR_INTERVAL, HANDLER(autoip_tmr)},
#endif /* LWIP_AUTOIP */
#if LWIP_IGMP
{IGMP_TMR_INTERVAL, HANDLER(igmp_tmr)},
#endif /* LWIP_IGMP */
#endif /* LWIP_IPV4 */
#if LWIP_DNS
{DNS_TMR_INTERVAL, HANDLER(dns_tmr)},
#endif /* LWIP_DNS */
#if LWIP_IPV6
{ND6_TMR_INTERVAL, HANDLER(nd6_tmr)},
#if LWIP_IPV6_REASS
{IP6_REASS_TMR_INTERVAL, HANDLER(ip6_reass_tmr)},
#endif /* LWIP_IPV6_REASS */
#if LWIP_IPV6_MLD
{MLD6_TMR_INTERVAL, HANDLER(mld6_tmr)},
#endif /* LWIP_IPV6_MLD */
#if LWIP_IPV6_DHCP6
{DHCP6_TIMER_MSECS, HANDLER(dhcp6_tmr)},
#endif /* LWIP_IPV6_DHCP6 */
#endif /* LWIP_IPV6 */
};
const int lwip_num_cyclic_timers = LWIP_ARRAYSIZE(lwip_cyclic_timers);
#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM
/** The one and only timeout list */
static struct sys_timeo *next_timeout;
static u32_t current_timeout_due_time;
#if LWIP_TESTMODE
struct sys_timeo**
sys_timeouts_get_next_timeout(void)
{
return &next_timeout;
}
#endif
#if LWIP_TCP
/** global variable that shows if the tcp timer is currently scheduled or not */
static int tcpip_tcp_timer_active;
/**
* Timer callback function that calls tcp_tmr() and reschedules itself.
*
* @param arg unused argument
*/
static void
tcpip_tcp_timer(void *arg)
{
LWIP_UNUSED_ARG(arg);
/* call TCP timer handler */
tcp_tmr();
/* timer still needed? */
if (tcp_active_pcbs || tcp_tw_pcbs) {
/* restart timer */
sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
} else {
/* disable timer */
tcpip_tcp_timer_active = 0;
}
}
/**
* Called from TCP_REG when registering a new PCB:
* the reason is to have the TCP timer only running when
* there are active (or time-wait) PCBs.
*/
void
tcp_timer_needed(void)
{
LWIP_ASSERT_CORE_LOCKED();
/* timer is off but needed again? */
if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) {
/* enable and start timer */
tcpip_tcp_timer_active = 1;
sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL);
}
}
#endif /* LWIP_TCP */
static void
#if LWIP_DEBUG_TIMERNAMES
sys_timeout_abs(u32_t abs_time, sys_timeout_handler handler, void *arg, const char *handler_name)
#else /* LWIP_DEBUG_TIMERNAMES */
sys_timeout_abs(u32_t abs_time, sys_timeout_handler handler, void *arg)
#endif
{
struct sys_timeo *timeout, *t;
timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT);
if (timeout == NULL) {
LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL);
return;
}
timeout->next = NULL;
timeout->h = handler;
timeout->arg = arg;
timeout->time = abs_time;
#if LWIP_DEBUG_TIMERNAMES
timeout->handler_name = handler_name;
LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p abs_time=%"U32_F" handler=%s arg=%p\n",
(void *)timeout, abs_time, handler_name, (void *)arg));
#endif /* LWIP_DEBUG_TIMERNAMES */
if (next_timeout == NULL) {
next_timeout = timeout;
return;
}
if (TIME_LESS_THAN(timeout->time, next_timeout->time)) {
timeout->next = next_timeout;
next_timeout = timeout;
} else {
for (t = next_timeout; t != NULL; t = t->next) {
if ((t->next == NULL) || TIME_LESS_THAN(timeout->time, t->next->time)) {
timeout->next = t->next;
t->next = timeout;
break;
}
}
}
}
/**
* Timer callback function that calls cyclic->handler() and reschedules itself.
*
* @param arg unused argument
*/
#if !LWIP_TESTMODE
static
#endif
void
lwip_cyclic_timer(void *arg)
{
u32_t now;
u32_t next_timeout_time;
const struct lwip_cyclic_timer *cyclic = (const struct lwip_cyclic_timer *)arg;
#if LWIP_DEBUG_TIMERNAMES
LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: %s()\n", cyclic->handler_name));
#endif
cyclic->handler();
now = sys_now();
next_timeout_time = (u32_t)(current_timeout_due_time + cyclic->interval_ms); /* overflow handled by TIME_LESS_THAN macro */
if (TIME_LESS_THAN(next_timeout_time, now)) {
/* timer would immediately expire again -> "overload" -> restart without any correction */
#if LWIP_DEBUG_TIMERNAMES
sys_timeout_abs((u32_t)(now + cyclic->interval_ms), lwip_cyclic_timer, arg, cyclic->handler_name);
#else
sys_timeout_abs((u32_t)(now + cyclic->interval_ms), lwip_cyclic_timer, arg);
#endif
} else {
/* correct cyclic interval with handler execution delay and sys_check_timeouts jitter */
#if LWIP_DEBUG_TIMERNAMES
sys_timeout_abs(next_timeout_time, lwip_cyclic_timer, arg, cyclic->handler_name);
#else
sys_timeout_abs(next_timeout_time, lwip_cyclic_timer, arg);
#endif
}
}
/** Initialize this module */
void sys_timeouts_init(void)
{
size_t i;
/* tcp_tmr() at index 0 is started on demand */
for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE(lwip_cyclic_timers); i++) {
/* we have to cast via size_t to get rid of const warning
(this is OK as cyclic_timer() casts back to const* */
sys_timeout(lwip_cyclic_timers[i].interval_ms, lwip_cyclic_timer, LWIP_CONST_CAST(void *, &lwip_cyclic_timers[i]));
}
}
/**
* Create a one-shot timer (aka timeout). Timeouts are processed in the
* following cases:
* - while waiting for a message using sys_timeouts_mbox_fetch()
* - by calling sys_check_timeouts() (NO_SYS==1 only)
*
* @param msecs time in milliseconds after that the timer should expire
* @param handler callback function to call when msecs have elapsed
* @param arg argument to pass to the callback function
*/
#if LWIP_DEBUG_TIMERNAMES
void
sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char *handler_name)
#else /* LWIP_DEBUG_TIMERNAMES */
void
sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
#endif /* LWIP_DEBUG_TIMERNAMES */
{
u32_t next_timeout_time;
LWIP_ASSERT_CORE_LOCKED();
LWIP_ASSERT("Timeout time too long, max is LWIP_UINT32_MAX/4 msecs", msecs <= (LWIP_UINT32_MAX / 4));
next_timeout_time = (u32_t)(sys_now() + msecs); /* overflow handled by TIME_LESS_THAN macro */
#if LWIP_DEBUG_TIMERNAMES
sys_timeout_abs(next_timeout_time, handler, arg, handler_name);
#else
sys_timeout_abs(next_timeout_time, handler, arg);
#endif
}
/**
* Go through timeout list (for this task only) and remove the first matching
* entry (subsequent entries remain untouched), even though the timeout has not
* triggered yet.
*
* @param handler callback function that would be called by the timeout
* @param arg callback argument that would be passed to handler
*/
void
sys_untimeout(sys_timeout_handler handler, void *arg)
{
struct sys_timeo *prev_t, *t;
LWIP_ASSERT_CORE_LOCKED();
if (next_timeout == NULL) {
return;
}
for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) {
if ((t->h == handler) && (t->arg == arg)) {
/* We have a match */
/* Unlink from previous in list */
if (prev_t == NULL) {
next_timeout = t->next;
} else {
prev_t->next = t->next;
}
memp_free(MEMP_SYS_TIMEOUT, t);
return;
}
}
return;
}
/**
* @ingroup lwip_nosys
* Handle timeouts for NO_SYS==1 (i.e. without using
* tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout
* handler functions when timeouts expire.
*
* Must be called periodically from your main loop.
*/
void
sys_check_timeouts(void)
{
u32_t now;
LWIP_ASSERT_CORE_LOCKED();
/* Process only timers expired at the start of the function. */
now = sys_now();
do {
struct sys_timeo *tmptimeout;
sys_timeout_handler handler;
void *arg;
PBUF_CHECK_FREE_OOSEQ();
tmptimeout = next_timeout;
if (tmptimeout == NULL) {
return;
}
if (TIME_LESS_THAN(now, tmptimeout->time)) {
return;
}
/* Timeout has expired */
next_timeout = tmptimeout->next;
handler = tmptimeout->h;
arg = tmptimeout->arg;
current_timeout_due_time = tmptimeout->time;
#if LWIP_DEBUG_TIMERNAMES
if (handler != NULL) {
LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s t=%"U32_F" arg=%p\n",
tmptimeout->handler_name, sys_now() - tmptimeout->time, arg));
}
#endif /* LWIP_DEBUG_TIMERNAMES */
memp_free(MEMP_SYS_TIMEOUT, tmptimeout);
if (handler != NULL) {
handler(arg);
}
LWIP_TCPIP_THREAD_ALIVE();
/* Repeat until all expired timers have been called */
} while (1);
}
/** Rebase the timeout times to the current time.
* This is necessary if sys_check_timeouts() hasn't been called for a long
* time (e.g. while saving energy) to prevent all timer functions of that
* period being called.
*/
void
sys_restart_timeouts(void)
{
u32_t now;
u32_t base;
struct sys_timeo *t;
if (next_timeout == NULL) {
return;
}
now = sys_now();
base = next_timeout->time;
for (t = next_timeout; t != NULL; t = t->next) {
t->time = (t->time - base) + now;
}
}
/** Return the time left before the next timeout is due. If no timeouts are
* enqueued, returns 0xffffffff
*/
u32_t
sys_timeouts_sleeptime(void)
{
u32_t now;
LWIP_ASSERT_CORE_LOCKED();
if (next_timeout == NULL) {
return SYS_TIMEOUTS_SLEEPTIME_INFINITE;
}
now = sys_now();
if (TIME_LESS_THAN(next_timeout->time, now)) {
return 0;
} else {
u32_t ret = (u32_t)(next_timeout->time - now);
LWIP_ASSERT("invalid sleeptime", ret <= LWIP_MAX_TIMEOUT);
return ret;
}
}
#else /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */
/* Satisfy the TCP code which calls this function */
void
tcp_timer_needed(void)
{
}
#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+192
View File
@@ -0,0 +1,192 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DHCPS_H__
#define __DHCPS_H__
//#include "sdkconfig.h"
#include <stdbool.h>
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct dhcps_state{
s16_t state;
} dhcps_state;
typedef struct dhcps_msg {
uint8_t op, htype, hlen, hops;// operation code, hw type, hw addr len, hops
uint8_t xid[4];// transaction id
uint16_t secs, flags; // seconds, flags
uint8_t ciaddr[4];// client ip addr
uint8_t yiaddr[4];// your ip addr
uint8_t siaddr[4];// server ip addr
uint8_t giaddr[4];// GW ip
uint8_t chaddr[16];// client hw address
uint8_t sname[64];// server name
uint8_t file[128];// boot filename
uint8_t options[312];
}dhcps_msg;
/* Defined in esp_misc.h */
typedef struct {
bool enable;
ip4_addr_t start_ip;
ip4_addr_t end_ip;
} dhcps_lease_t;
enum dhcps_offer_option{
OFFER_START = 0x00,
OFFER_ROUTER = 0x01,
OFFER_DNS = 0x02,
OFFER_END
};
/** @brief DHCP server's description of compile time configuration values in dhcpserver.c
*
* - DHCPS_DEBUG: Prints very detailed debug messages if set to 1, hardcoded to 0
* - USE_CLASS_B_NET: Use class B network mask if enabled, not-defined (could be enabled as CC_FLAGS)
* - MAX_STATION_NUM: Maximum number of clients, set to Kconfig value CONFIG_LWIP_DHCPS_MAX_STATION_NUM
* - LWIP_HOOK_DHCPS_POST_STATE: Used to inject user code after parsing DHCP message, not defined
* - could be enabled in lwipopts.h or via CC_FLAGS
* - basic usage of the hook to print hex representation of the entire option field is below:
* #define LWIP_HOOK_DHCPS_POST_STATE(msg, len, state) \
* ({ s16_t ret = state; if (state == DHCPS_STATE_ACK) { ESP_LOG_BUFFER_HEXDUMP("DHCPS",msg->options, 312, ESP_LOG_INFO);} ret; })
*/
/**
* @brief Definitions related to lease time, units and limits
*/
#define DHCPS_COARSE_TIMER_SECS 1
#define DHCPS_MAX_LEASE 0x64
#define DHCPS_LEASE_TIME_DEF (120)
#define DHCPS_LEASE_UNIT CONFIG_LWIP_DHCPS_LEASE_UNIT
struct dhcps_pool{
ip4_addr_t ip;
u8_t mac[6];
u32_t lease_timer;
};
typedef u32_t dhcps_time_t;
typedef u8_t dhcps_offer_t;
typedef struct {
dhcps_offer_t dhcps_offer;
dhcps_offer_t dhcps_dns;
dhcps_time_t dhcps_time;
dhcps_lease_t dhcps_poll;
} dhcps_options_t;
typedef void (*dhcps_cb_t)(void* cb_arg, u8_t client_ip[4], u8_t client_mac[6]);
static inline bool dhcps_router_enabled (dhcps_offer_t offer)
{
return (offer & OFFER_ROUTER) != 0;
}
static inline bool dhcps_dns_enabled (dhcps_offer_t offer)
{
return (offer & OFFER_DNS) != 0;
}
typedef struct dhcps_t dhcps_t;
/**
* @brief Creates new DHCP server object
*
* @return Pointer to the DHCP server handle on success, NULL on error
*/
dhcps_t *dhcps_new(void);
/**
* @brief Deletes supplied DHPC server object
*
* @warning This may not delete the handle immediately if the server wasn't
* stopped properly, but mark for deleting once the timer callback occurs
*
* @param dhcps Pointer to the DHCP handle
*/
void dhcps_delete(dhcps_t *dhcps);
/**
* @brief Starts the DHCP server on the specified network interface
*
* @param dhcps Pointer to the DHCP handle
* @param netif Pointer to the lwIP's network interface struct
* @param ip DHCP server's address
* @return ERR_ARG if invalid args, ERR_OK on success
*/
err_t dhcps_start(dhcps_t *dhcps, struct netif *netif, ip4_addr_t ip);
/**
* @brief Stops the DHCP server on the specified netif
* @param dhcps Pointer to the DHCP handle
* @param netif Pointer to the lwIP's network interface struct
* @return ERR_ARG if invalid args, ERR_OK on success
*/
err_t dhcps_stop(dhcps_t *dhcps, struct netif *netif);
/**
* @brief Gets the DHCP server option info
* @param dhcps Pointer to the DHCP handle
* @param op_id DHCP message option id
* @param opt_len DHCP message option length
* @return DHCP message option addr
*/
void *dhcps_option_info(dhcps_t *dhcps, u8_t op_id, u32_t opt_len);
/**
* @brief Sets the DHCP server option info
* @param dhcps Pointer to the DHCP handle
* @param op_id DHCP message option id
* @param opt_info DHCP message option info
* @param opt_len DHCP message option length
* @return ERR_ARG if invalid args, ERR_OK on success
*/
err_t dhcps_set_option_info(dhcps_t *dhcps, u8_t op_id, void *opt_info, u32_t opt_len);
/**
* @brief Tries to find IP address corresponding to the supplied MAC
* @param dhcps Pointer to the DHCP handle
* @param mac Supplied MAC address
* @param ip Pointer to the resultant IP address
* @return True if the IP address has been found
*/
bool dhcp_search_ip_on_mac(dhcps_t *dhcps, u8_t *mac, ip4_addr_t *ip);
/**
* @brief Sets DNS server address for the DHCP server
* @param dhcps Pointer to the DHCP handle
* @param dnsserver Address of the DNS server
* @return ERR_ARG if invalid handle, ERR_OK on success
*/
err_t dhcps_dns_setserver(dhcps_t *dhcps, const ip_addr_t *dnsserver);
/**
* @brief Gets DNS server associated with this DHCP server
* @param dhcps Pointer to the DHCP handle
* @param dnsserver Address of the DNS server
* @return ERR_ARG if invalid handle, ERR_OK on success
*/
err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver);
/**
* @brief Sets callback on assigning an IP to the connected client
* @param dhcps Pointer to the DHCP handle
* @param cb Callback for dhcp server
* @param cb_arg Context pointer to be added to the callback
* @return ERR_ARG if invalid handle, ERR_OK on success
*/
err_t dhcps_set_new_lease_cb(dhcps_t *dhcps, dhcps_cb_t cb, void* cb_arg);
#ifdef __cplusplus
}
#endif
#endif /* __DHCPS_H__ */
@@ -0,0 +1,147 @@
// Copyright 2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#define ESP_DHCPS 1
#define DHCP_COARSE_TIMER_MSECS 1000
#define CONFIG_LWIP_DHCPS_MAX_STATION_NUM 500
#define DHCPS_LEASE_UNIT 1000
#ifdef __cplusplus
extern "C" {
#endif
/** DHCP Options
This macros are not part of the public dhcpserver.h interface.
**/
typedef enum
{
/* RFC 1497 Vendor Extensions */
PAD = 0,
END = 255,
SUBNET_MASK = 1,
TIME_OFFSET = 2,
ROUTER = 3,
TIME_SERVER = 4,
NAME_SERVER = 5,
DOMAIN_NAME_SERVER = 6,
LOG_SERVER = 7,
COOKIE_SERVER = 8,
LPR_SERVER = 9,
IMPRESS_SERVER = 10,
RESOURCE_LOCATION_SERVER = 11,
HOST_NAME = 12,
BOOT_FILE_SIZE = 13,
MERIT_DUMP_FILE = 14,
DOMAIN_NAME = 15,
SWAP_SERVER = 16,
ROOT_PATH = 17,
EXTENSIONS_PATH = 18,
/* IP Layer Parameters per Host */
IP_FORWARDING = 19,
NON_LOCAL_SOURCE_ROUTING = 20,
POLICY_FILTER = 21,
MAXIMUM_DATAGRAM_REASSEMBLY_SIZE = 22,
DEFAULT_IP_TIME_TO_LIVE = 23,
PATH_MTU_AGING_TIMEOUT = 24,
PATH_MTU_PLATEAU_TABLE = 25,
/* IP Layer Parameters per Interface */
INTERFACE_MTU = 26,
ALL_SUBNETS_ARE_LOCAL = 27,
BROADCAST_ADDRESS = 28,
PERFORM_MASK_DISCOVERY = 29,
MASK_SUPPLIER = 30,
PERFORM_ROUTER_DISCOVERY = 31,
ROUTER_SOLICITATION_ADDRESS = 32,
STATIC_ROUTE = 33,
/* Link Layer Parameters per Interface */
TRAILER_ENCAPSULATION = 34,
ARP_CACHE_TIMEOUT = 35,
ETHERNET_ENCAPSULATION = 36,
/* TCP Parameters */
TCP_DEFAULT_TTL = 37,
TCP_KEEPALIVE_INTERVAL = 38,
TCP_KEEPALIVE_GARBAGE = 39,
/* Application and Service Parameters */
NETWORK_INFORMATION_SERVICE_DOMAIN = 40,
NETWORK_INFORMATION_SERVERS = 41,
NETWORK_TIME_PROTOCOL_SERVERS = 42,
VENDOR_SPECIFIC_INFORMATION = 43,
NETBIOS_OVER_TCP_IP_NAME_SERVER = 44,
NETBIOS_OVER_TCP_IP_DATAGRAM_DISTRIBUTION_SERVER = 45,
NETBIOS_OVER_TCP_IP_NODE_TYPE = 46,
NETBIOS_OVER_TCP_IP_SCOPE = 47,
X_WINDOW_SYSTEM_FONT_SERVER = 48,
X_WINDOW_SYSTEM_DISPLAY_MANAGER = 49,
NETWORK_INFORMATION_SERVICE_PLUS_DOMAIN = 64,
NETWORK_INFORMATION_SERVICE_PLUS_SERVERS = 65,
MOBILE_IP_HOME_AGENT = 68,
SMTP_SERVER = 69,
POP3_SERVER = 70,
NNTP_SERVER = 71,
DEFAULT_WWW_SERVER = 72,
DEFAULT_FINGER_SERVER = 73,
DEFAULT_IRC_SERVER = 74,
STREETTALK_SERVER = 75,
STREETTALK_DIRECTORY_ASSISTANCE_SERVER = 76,
/* DHCP Extensions */
REQUESTED_IP_ADDRESS = 50,
IP_ADDRESS_LEASE_TIME = 51,
OPTION_OVERLOAD = 52,
TFTP_SERVER_NAME = 66,
BOOTFILE_NAME = 67,
DHCP_MESSAGE_TYPE = 53,
SERVER_IDENTIFIER = 54,
PARAMETER_REQUEST_LIST = 55,
MESSAGE = 56,
MAXIMUM_DHCP_MESSAGE_SIZE = 57,
RENEWAL_T1_TIME_VALUE = 58,
REBINDING_T2_TIME_VALUE = 59,
VENDOR_CLASS_IDENTIFIER = 60,
CLIENT_IDENTIFIER = 61,
USER_CLASS = 77,
FQDN = 81,
DHCP_AGENT_OPTIONS = 82,
NDS_SERVERS = 85,
NDS_TREE_NAME = 86,
NDS_CONTEXT = 87,
CLIENT_LAST_TRANSACTION_TIME = 91,
ASSOCIATED_IP = 92,
USER_AUTHENTICATION_PROTOCOL = 98,
AUTO_CONFIGURE = 116,
NAME_SERVICE_SEARCH = 117,
SUBNET_SELECTION = 118,
DOMAIN_SEARCH = 119,
CLASSLESS_ROUTE = 121,
} dhcp_msg_option;
#ifdef __cplusplus
}
#endif
+255
View File
@@ -0,0 +1,255 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "lwip/opt.h"
#include "lwip/udp.h"
#include "lwip/mem.h"
#include "dnsproxy.h"
#include "eth_router.h"
#include "eth_queue.h"
static u8_t mdns_payload[DNS_MSG_SIZE];
static struct udp_pcb *pdns_pcb = NULL;
struct ETH_Q dns_q;
static struct NHandle_t tNotifyHandle;
static pthread_t tHandle;
#define MDNS_MAX_NAME_LENGTH (256)
struct __attribute__((__packed__)) mdns_hdr {
u16_t id;
u8_t flags1;
u8_t flags2;
u16_t numquestions;
u16_t numanswers;
u16_t numauthrr;
u16_t numextrarr;
};
#define SIZEOF_DNS_HDR 12
struct __attribute__((__packed__)) mdns_query {
/* MDNS query record starts with either a domain name or a pointer
to a name already present somewhere in the packet. */
u16_t type;
u16_t class;
};
#define SIZEOF_DNS_QUERY 4
struct __attribute__((__packed__)) mdns_answer {
/* MDNS answer record starts with either a domain name or a pointer
to a name already present somewhere in the packet. */
u16_t type;
u16_t class;
u32_t ttl;
u16_t len;
};
#define SIZEOF_DNS_ANSWER 10
struct DNS_RECORD {
uint16_t query_type;
uint16_t query_class;
uint8_t name[512];
uint32_t ip;
uint16_t port;
uint16_t id;
};
static int query_decode(uint8_t* query, int len, struct DNS_RECORD* out) {
int pos=0;
int outpos=0;
do {
if (pos>=len) return -1;
uint8_t nlen=query[pos++];
if (nlen==0) break;
if (outpos+nlen>=sizeof(out->name)-1) return -1;
if (pos+nlen>len) return -1;
for (int i=0; i<nlen; i++) out->name[outpos++]=query[pos++];
out->name[outpos++]='.';
} while(1);
if (pos+4>len) return -1;
if (outpos>0) outpos--;
out->name[outpos]=0;
out->query_type=(query[pos]<<8)+query[pos+1];
out->query_class=(query[pos+2]<<8)+query[pos+3];
return pos+4;
}
static void pdns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *iaddr, u16_t port) {
u8_t i;
struct mdns_hdr *hdr;
u8_t nquestions;
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(pcb);
struct mdns_info *info = (struct mdns_info *)arg;
/* is the dns message too big ? */
if (p->tot_len > DNS_MSG_SIZE) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n"));
/* free pbuf and return */
goto memerr1;
}
/* is the dns message big enough ? */
if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + SIZEOF_DNS_ANSWER)) {
LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n"));
/* free pbuf and return */
goto memerr1;
}
/* copy dns payload inside static buffer for processing */
if (pbuf_copy_partial(p, mdns_payload, p->tot_len, 0) != p->tot_len) goto memerr1;
hdr = (struct mdns_hdr*) mdns_payload;
uint8_t* data=(uint8_t*) mdns_payload + SIZEOF_DNS_HDR;
struct ETH_PBUF* p_req=eth_pbuf_alloc(&xeth_pbuf_ctrl, NULL);
if (p_req==NULL) goto memerr1;
print_log("DNS request: id=%04X fg1=%02X fg2=%02X nq=%d na=%d", htons(hdr->id), hdr->flags1, hdr->flags2, htons(hdr->numquestions), htons(hdr->numanswers));
int num_q=htons(hdr->numquestions);
int num_a=htons(hdr->numanswers);
if (num_a!=0) goto memerr2;
if (num_q!=1) goto memerr2;
int remain_len=p->tot_len-SIZEOF_DNS_HDR;
struct DNS_RECORD* rec=(struct DNS_RECORD*)p_req->pbuf.payload;
int len=query_decode(data, remain_len, rec);
if (len<0) goto memerr2;
rec->id=htons(hdr->id);
rec->ip=*(uint32_t*)iaddr;
rec->port=port;
print_log("DNS request: <%s> from ip=%d.%d.%d.%d port=%d", rec->name, (rec->ip)&0xff, (rec->ip>>8)&0xff, (rec->ip>>16)&0xff, (rec->ip>>24)&0xff, rec->port);
add_to_custom_queue(&p_req->pbuf, &dns_q);
TNotifyAdd( &tNotifyHandle, 1);
goto memerr1;
memerr2:
eth_pbuf_free_request(p_req);
memerr1:
pbuf_free(p);
return;
}
// a a a . b b b . c c c 0
// 3 a a a 3 b b b 3 c c c 0
// 0 1 2 3 4 5 6 7 8 9 B C D
int dns_encode_name(uint8_t* dst, uint8_t* str) {
int pos=0;
int cnt=0;
do {
if (str[pos]=='.') { dst[pos-cnt]=cnt; cnt=0; pos++; continue;}
if (str[pos]==0) { dst[pos-cnt]=cnt; dst[pos+1]=0; pos+=2; break; }
dst[pos+1]=str[pos];
pos++; cnt++;
} while(1);
return pos;
}
_Noreturn void dnsproxy_thread(void* arg) {
struct pbuf* p;
while (1) {
uint32_t res=TNotifyWait( &tNotifyHandle );
do {
p=get_from_custom_queue(&dns_q);
if (p==NULL) break;
struct DNS_RECORD* rec=(struct DNS_RECORD*)p->payload;
int status;
struct addrinfo hints;
struct addrinfo *servinfo; // указатель на результаты
memset(&hints, 0, sizeof hints); // убедимся, что структура пуста
hints.ai_family = PF_INET;//AF_UNSPEC - AF_INET; // неважно, IPv4 или IPv6
hints.ai_socktype = SOCK_STREAM; // TCP stream-sockets
hints.ai_flags = AI_PASSIVE; // заполните мой IP-адрес за меняif ((status = getaddrinfo(NULL, «3490», &hints, &servinfo)) != 0) {
status = getaddrinfo(rec->name, NULL, &hints, &servinfo);// servinfo теперь —
if (status==0 && servinfo->ai_family==AF_INET) {
uint8_t* ip=(uint8_t*)&((struct sockaddr_in *)servinfo->ai_addr)->sin_addr;
print_log("DNS query service: <%s> IP=%d.%d.%d.%d", rec->name, ip[0], ip[1], ip[2], ip[3]);
struct pbuf* p1 = pbuf_alloc(PBUF_TRANSPORT, 1400, PBUF_RAM);
if (p1 != NULL) {
int pos=0;
struct mdns_hdr* hdr=p1->payload;
hdr->id=htons(rec->id);
hdr->flags1=0x81;
hdr->flags2=0x80;
// FLAGS1 FLAGS2 Flags: 0x8180 Standard query response, No error
// 1... .... .... .... = Response: Message is a response
// .000 0... .... .... = Opcode: Standard query (0)
// .... .0.. .... .... = Authoritative: Server is not an authority for domain
// .... ..0. .... .... = Truncated: Message is not truncated
// .... ...1 .... .... = Recursion desired: Do query recursively
// .... .... 1... .... = Recursion available: Server can do recursive queries
// .... .... .0.. .... = Z: reserved (0)
// .... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
// .... .... ...0 .... = Non-authenticated data: Unacceptable
// .... .... .... 0000 = Reply code: No error (0)
hdr->numquestions=htons(1);
hdr->numanswers=htons(1);
hdr->numauthrr=htons(0);
hdr->numextrarr=htons(0);
uint8_t dpos=sizeof(struct mdns_hdr);
uint8_t* rsp=(uint8_t*)p1->payload;
int ret=dns_encode_name(rsp+dpos, rec->name);
if (ret>0) {
dpos += ret;
rsp[dpos++]=0;// TYPE
rsp[dpos++]=1;
rsp[dpos++]=0;// CLASS
rsp[dpos++]=1;
rsp[dpos++]=0xc0;// answer: name
rsp[dpos++]=0x0c;
rsp[dpos++]=0;// type
rsp[dpos++]=1;
rsp[dpos++]=0;// class
rsp[dpos++]=1;
rsp[dpos++]=0;// TTL
rsp[dpos++]=0;// TTL
rsp[dpos++]=0x27;// TTL
rsp[dpos++]=0x10;// TTL
rsp[dpos++]=0;// data length
rsp[dpos++]=4;// data length
rsp[dpos++]=ip[0];
rsp[dpos++]=ip[1];
rsp[dpos++]=ip[2];
rsp[dpos++]=ip[3];
p1->len=dpos;
p1->tot_len=dpos;
char ans[3000]; int pt=0;
for (int i=0; i<dpos; i++) {pt+=sprintf(ans+pt,"%02X ",rsp[i]);}
print_log("DNS answer: <%s>", ans);
udp_sendto(pdns_pcb, p1, &rec->ip, rec->port);
}
pbuf_free(p1);
}
} else print_log("DNS query err (status=%d)", status);
pbuf_free(p);
} while(1);
}
}
void dnsproxy_init() {
dns_q.q_len_max=5;
int ret;
pdns_pcb = udp_new();
if (pdns_pcb) {
ret=udp_bind(pdns_pcb, IP_ADDR_ANY, 53);
if (ret) return;
udp_recv(pdns_pcb, pdns_recv, NULL);
}
TaskCreate (dnsproxy_thread, &tHandle);
TNotifyCreate(&tNotifyHandle);
}
+3
View File
@@ -0,0 +1,3 @@
#define DNS_MSG_SIZE 1500
void dnsproxy_init();
@@ -0,0 +1,150 @@
// LWIP interface for router
#include <string.h>
#include "lwip/lwip.h"
#include "lwip/opt.h"
#include "lwip/timeouts.h"
#include "netif/ethernet.h"
#include "netif/etharp.h"
#include "lwip/tcpip.h"
#include "lwip/pbuf.h"
#include "eth_mem.h"
#include "eth_router_cfg.h"
#include "eth_router.h"
#include "lwip/eth_router_if_lwip.h"
static struct ETH_QUEUEPOOL_CTRL* if_pool=&xeth_queuepool_ctrl;
struct netif* lwip_netif;
static pthread_t xLWIP_input_task;
static pthread_t xLWIP_tmr_task;
struct NHandle_t TTskHandle;
struct ETH_IF_LWIP_STATS eth_if_lwip;
static char if_name[]="LWIP";
struct ETH_PBUF* block_to_send;
//#pragma optimize=none
static err_t lwip_output_to_bridge(struct netif *netif, struct pbuf *p) {
if (p->tot_len>ETH_MEM_BUF_SIZE) {
eth_if_lwip.in_too_big++;
return ERR_OK;
}
struct ETH_PBUF* block=eth_pbuf_alloc(&xeth_pbuf_ctrl, NULL);
if (block==NULL) {
eth_if_lwip.in_alloc_errs++;
return ERR_OK;
}
int ptr=0;
struct pbuf *frag;
for (frag=p; frag!=NULL; frag=frag->next) {// copy datagram payload from LWIP to ETH_MEM pbuf
if (frag->len+ptr<=ETH_MEM_BUF_SIZE) memcpy((uint8_t*)block->pbuf.payload+ptr, frag->payload, frag->len);
else {
eth_pbuf_free_request(block);
eth_if_lwip.in_too_big++;
return ERR_OK;
}
ptr+=frag->len;
}
// print_log("dgram from LWIP, size=%d",ptr);
block->pbuf.len=ptr;
block->pbuf.tot_len=ptr;
block->pbuf.if_idx=LWIP_NETIF_ID;
for (int i=0; i<6; i++) ((uint8_t*)(block->pbuf.payload))[i+6]=netif->hwaddr[i];
eth_add_packet_to_router_queue(block);
return ERR_OK;
}
static void to_lwip_QueueTask(void* arg) {
print_log("********** LWIP task started");
while (1) {
int res=TNotifyWait( &TTskHandle );
if (res & 2) {
LOCK_LWIP_CORE();
sys_check_timeouts();
UNLOCK_LWIP_CORE();
}
if (res & 1) do {
if (block_to_send->pbuf.ref==0) while(1);
int in=0;
int err=1;
LOCK_LWIP_CORE();
if (lwip_netif->input) err=lwip_netif->input(&block_to_send->pbuf, lwip_netif);
UNLOCK_LWIP_CORE();
// if (err == ERR_OK) in=1;
// print_log("dgram to LWIP, size=%d",block_to_send->pbuf.len);
if (err != ERR_OK) eth_pbuf_free_request(block_to_send);
// if (in==0) {
// eth_if_lwip.lwip_out_errs++; eth_if_lwip.lwip_out_err=err;
// LOCK_LWIP_CORE();
// if (lwip_netif->input) err=lwip_netif->input(&block_to_send->pbuf, lwip_netif);
// UNLOCK_LWIP_CORE();
// if (err) eth_pbuf_free_request(block_to_send);
// }
block_to_send=NULL;
struct ETH_PBUF* tb=eth_get_packet(&if_pool->eth_netif_array[LWIP_NETIF_ID]);
if (tb) block_to_send=tb;
} while (block_to_send);
}
}
static void to_lwip_TmrTask(void* arg) {
while(1) {
TNotifyAdd( &TTskHandle, 2);
usleep(1000*100);
}
}
static void lwip_callback_from_bridge(struct ETH_PBUF* block, struct ETH_NETIF* enetif) {
block_to_send=block;
TNotifyAdd( &TTskHandle, 1);
}
err_t eth_lwip_if_init(struct netif *netif) {
LWIP_ASSERT("netif != NULL", (netif != NULL));
lwip_netif=netif;
netif->name[0] = 'L';
netif->name[1] = 'W';
print_log("********** LWIP interface init");
netif->output = etharp_output;
netif->linkoutput = lwip_output_to_bridge;//low_level_output;
for (int i=0; i<6; i++) netif->hwaddr[i] = rand();
netif->hwaddr[0]=0x00;
netif->hwaddr[1]=0x80;
netif->hwaddr_len = ETH_HWADDR_LEN;
netif->mtu = 1500;//ETH_MAX_PAYLOAD;
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
if (xLWIP_input_task==NULL) {
if_pool->eth_netif_array[LWIP_NETIF_ID].callback_fn=lwip_callback_from_bridge;
TaskCreate (to_lwip_QueueTask, &xLWIP_input_task);
TaskCreate (to_lwip_TmrTask, &xLWIP_tmr_task);
TNotifyCreate(&TTskHandle);
while ( eth_get_packet(&if_pool->eth_netif_array[LWIP_NETIF_ID]) );
}
if_pool->eth_netif_array[LWIP_NETIF_ID].q_output_len_max=LWIP_NETIF_QLEN;
if_pool->eth_netif_array[LWIP_NETIF_ID].if_name=if_name;
netif_set_up(netif);
netif_set_link_up(netif);
if_pool->eth_netif_array[LWIP_NETIF_ID].if_up=1;
return ERR_OK;
}
@@ -0,0 +1,13 @@
#define LWIP_TASK_STACK_SIZE 1024// x4 bytes
err_t eth_lwip_if_init(struct netif *netif);
extern struct netif* lwip_netif;
struct ETH_IF_LWIP_STATS {
uint32_t in_frags;
uint32_t in_too_big;
uint32_t in_alloc_errs;
uint32_t lwip_out_errs;
err_enum_t lwip_out_err;
};
extern struct ETH_IF_LWIP_STATS eth_if_lwip;
@@ -0,0 +1,87 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_ARCH_CC_H
#define LWIP_ARCH_CC_H
/* see https://sourceforge.net/p/predef/wiki/OperatingSystems/ */
#if defined __ANDROID__
#define LWIP_UNIX_ANDROID
#elif defined __linux__
#define LWIP_UNIX_LINUX
#elif defined __APPLE__
#define LWIP_UNIX_MACH
#elif defined __OpenBSD__
#define LWIP_UNIX_OPENBSD
#elif defined __CYGWIN__
#define LWIP_UNIX_CYGWIN
#elif defined __GNU__
#define LWIP_UNIX_HURD
#endif
#define LWIP_TIMEVAL_PRIVATE 0
#include <sys/time.h>
#define LWIP_ERRNO_INCLUDE <errno.h>
#if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD)
#define LWIP_ERRNO_STDINCLUDE 1
#endif
//extern unsigned int lwip_port_rand(void);
#define LWIP_RAND() (rand())
/* different handling for unit test, normally not needed */
#ifdef LWIP_NOASSERT_ON_ERROR
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
handler;}} while(0)
#endif
#if defined(LWIP_UNIX_ANDROID) && defined(FD_SET)
//typedef __kernel_fd_set fd_set;
#endif
#if defined(LWIP_UNIX_MACH)
/* sys/types.h and signal.h bring in Darwin byte order macros. pull the
header here and disable LwIP's version so that apps still can get
the macros via LwIP headers and use system headers */
#include <sys/types.h>
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
#endif
struct sio_status_s;
typedef struct sio_status_s sio_status_t;
#define sio_fd_t sio_status_t*
#define __sio_fd_t_defined
typedef unsigned int sys_prot_t;
#endif /* LWIP_ARCH_CC_H */
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_ARCH_PERF_H
#define LWIP_ARCH_PERF_H
#include <sys/times.h>
#ifdef PERF
#define PERF_START { \
unsigned long __c1l, __c1h, __c2l, __c2h; \
__asm__(".byte 0x0f, 0x31" : "=a" (__c1l), "=d" (__c1h))
#define PERF_STOP(x) __asm__(".byte 0x0f, 0x31" : "=a" (__c2l), "=d" (__c2h)); \
perf_print(__c1l, __c1h, __c2l, __c2h, x);}
/*#define PERF_START do { \
struct tms __perf_start, __perf_end; \
times(&__perf_start)
#define PERF_STOP(x) times(&__perf_end); \
perf_print_times(&__perf_start, &__perf_end, x);\
} while(0)*/
#else /* PERF */
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* PERF */
void perf_print(unsigned long c1l, unsigned long c1h,
unsigned long c2l, unsigned long c2h,
char *key);
void perf_print_times(struct tms *start, struct tms *end, char *key);
void perf_init(char *fname);
#endif /* LWIP_ARCH_PERF_H */
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_ARCH_SYS_ARCH_H
#define LWIP_ARCH_SYS_ARCH_H
#define SYS_MBOX_NULL NULL
#define SYS_SEM_NULL NULL
/*typedef u32_t sys_prot_t;*/
struct sys_sem;
typedef struct sys_sem * sys_sem_t;
#define sys_sem_valid(sem) (((sem) != NULL) && (*(sem) != NULL))
#define sys_sem_valid_val(sem) ((sem) != NULL)
#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; }}while(0)
#define sys_sem_set_invalid_val(sem) do { (sem) = NULL; }while(0)
struct sys_mutex;
typedef struct sys_mutex * sys_mutex_t;
#define sys_mutex_valid(mutex) sys_sem_valid(mutex)
#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
struct sys_mbox;
typedef struct sys_mbox * sys_mbox_t;
#define sys_mbox_valid(mbox) sys_sem_valid(mbox)
#define sys_mbox_valid_val(mbox) sys_sem_valid_val(mbox)
#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
#define sys_mbox_set_invalid_val(mbox) sys_sem_set_invalid_val(mbox)
struct sys_thread;
typedef struct sys_thread * sys_thread_t;
#define LWIP_EXAMPLE_APP_ABORT() lwip_unix_keypressed()
int lwip_unix_keypressed(void);
#endif /* LWIP_ARCH_SYS_ARCH_H */
@@ -0,0 +1,201 @@
/**
* @file
* Application layered TCP connection API (to be used from TCPIP thread)\n
*
* This file contains the generic API.
* For more details see @ref altcp_api.
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_H
#define LWIP_HDR_ALTCP_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/tcpbase.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
struct altcp_pcb;
struct altcp_functions;
typedef err_t (*altcp_accept_fn)(void *arg, struct altcp_pcb *new_conn, err_t err);
typedef err_t (*altcp_connected_fn)(void *arg, struct altcp_pcb *conn, err_t err);
typedef err_t (*altcp_recv_fn)(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err);
typedef err_t (*altcp_sent_fn)(void *arg, struct altcp_pcb *conn, u16_t len);
typedef err_t (*altcp_poll_fn)(void *arg, struct altcp_pcb *conn);
typedef void (*altcp_err_fn)(void *arg, err_t err);
typedef struct altcp_pcb* (*altcp_new_fn)(void *arg, u8_t ip_type);
struct altcp_pcb {
const struct altcp_functions *fns;
struct altcp_pcb *inner_conn;
void *arg;
void *state;
/* application callbacks */
altcp_accept_fn accept;
altcp_connected_fn connected;
altcp_recv_fn recv;
altcp_sent_fn sent;
altcp_poll_fn poll;
altcp_err_fn err;
u8_t pollinterval;
};
/** @ingroup altcp */
typedef struct altcp_allocator_s {
/** Allocator function */
altcp_new_fn alloc;
/** Argument to allocator function */
void *arg;
} altcp_allocator_t;
struct altcp_pcb *altcp_new(altcp_allocator_t *allocator);
struct altcp_pcb *altcp_new_ip6(altcp_allocator_t *allocator);
struct altcp_pcb *altcp_new_ip_type(altcp_allocator_t *allocator, u8_t ip_type);
void altcp_arg(struct altcp_pcb *conn, void *arg);
void altcp_accept(struct altcp_pcb *conn, altcp_accept_fn accept);
void altcp_recv(struct altcp_pcb *conn, altcp_recv_fn recv);
void altcp_sent(struct altcp_pcb *conn, altcp_sent_fn sent);
void altcp_poll(struct altcp_pcb *conn, altcp_poll_fn poll, u8_t interval);
void altcp_err(struct altcp_pcb *conn, altcp_err_fn err);
void altcp_recved(struct altcp_pcb *conn, u16_t len);
err_t altcp_bind(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port);
err_t altcp_connect(struct altcp_pcb *conn, const ip_addr_t *ipaddr, u16_t port, altcp_connected_fn connected);
/* return conn for source code compatibility to tcp callback API only */
struct altcp_pcb *altcp_listen_with_backlog_and_err(struct altcp_pcb *conn, u8_t backlog, err_t *err);
#define altcp_listen_with_backlog(conn, backlog) altcp_listen_with_backlog_and_err(conn, backlog, NULL)
/** @ingroup altcp */
#define altcp_listen(conn) altcp_listen_with_backlog_and_err(conn, TCP_DEFAULT_LISTEN_BACKLOG, NULL)
void altcp_abort(struct altcp_pcb *conn);
err_t altcp_close(struct altcp_pcb *conn);
err_t altcp_shutdown(struct altcp_pcb *conn, int shut_rx, int shut_tx);
err_t altcp_write(struct altcp_pcb *conn, const void *dataptr, u16_t len, u8_t apiflags);
err_t altcp_output(struct altcp_pcb *conn);
u16_t altcp_mss(struct altcp_pcb *conn);
u16_t altcp_sndbuf(struct altcp_pcb *conn);
u16_t altcp_sndqueuelen(struct altcp_pcb *conn);
void altcp_nagle_disable(struct altcp_pcb *conn);
void altcp_nagle_enable(struct altcp_pcb *conn);
int altcp_nagle_disabled(struct altcp_pcb *conn);
void altcp_setprio(struct altcp_pcb *conn, u8_t prio);
err_t altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
ip_addr_t *altcp_get_ip(struct altcp_pcb *conn, int local);
u16_t altcp_get_port(struct altcp_pcb *conn, int local);
#ifdef LWIP_DEBUG
enum tcp_state altcp_dbg_get_tcp_state(struct altcp_pcb *conn);
#endif
#ifdef __cplusplus
}
#endif
#else /* LWIP_ALTCP */
/* ALTCP disabled, define everything to link against tcp callback API (e.g. to get a small non-ssl httpd) */
#include "lwip/tcp.h"
#define altcp_accept_fn tcp_accept_fn
#define altcp_connected_fn tcp_connected_fn
#define altcp_recv_fn tcp_recv_fn
#define altcp_sent_fn tcp_sent_fn
#define altcp_poll_fn tcp_poll_fn
#define altcp_err_fn tcp_err_fn
#define altcp_pcb tcp_pcb
#define altcp_tcp_new_ip_type tcp_new_ip_type
#define altcp_tcp_new tcp_new
#define altcp_tcp_new_ip6 tcp_new_ip6
#define altcp_new(allocator) tcp_new()
#define altcp_new_ip6(allocator) tcp_new_ip6()
#define altcp_new_ip_type(allocator, ip_type) tcp_new_ip_type(ip_type)
#define altcp_arg tcp_arg
#define altcp_accept tcp_accept
#define altcp_recv tcp_recv
#define altcp_sent tcp_sent
#define altcp_poll tcp_poll
#define altcp_err tcp_err
#define altcp_recved tcp_recved
#define altcp_bind tcp_bind
#define altcp_connect tcp_connect
#define altcp_listen_with_backlog_and_err tcp_listen_with_backlog_and_err
#define altcp_listen_with_backlog tcp_listen_with_backlog
#define altcp_listen tcp_listen
#define altcp_abort tcp_abort
#define altcp_close tcp_close
#define altcp_shutdown tcp_shutdown
#define altcp_write tcp_write
#define altcp_output tcp_output
#define altcp_mss tcp_mss
#define altcp_sndbuf tcp_sndbuf
#define altcp_sndqueuelen tcp_sndqueuelen
#define altcp_nagle_disable tcp_nagle_disable
#define altcp_nagle_enable tcp_nagle_enable
#define altcp_nagle_disabled tcp_nagle_disabled
#define altcp_setprio tcp_setprio
#define altcp_get_tcp_addrinfo tcp_get_tcp_addrinfo
#define altcp_get_ip(pcb, local) ((local) ? (&(pcb)->local_ip) : (&(pcb)->remote_ip))
#ifdef LWIP_DEBUG
#define altcp_dbg_get_tcp_state tcp_dbg_get_tcp_state
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_H */
@@ -0,0 +1,72 @@
/**
* @file
* Application layered TCP connection API (to be used from TCPIP thread)\n
* This interface mimics the tcp callback API to the application while preventing
* direct linking (much like virtual functions).
* This way, an application can make use of other application layer protocols
* on top of TCP without knowing the details (e.g. TLS, proxy connection).
*
* This file contains the base implementation calling into tcp.
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_TCP_H
#define LWIP_HDR_ALTCP_TCP_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/altcp.h"
#ifdef __cplusplus
extern "C" {
#endif
struct altcp_pcb *altcp_tcp_new_ip_type(u8_t ip_type);
#define altcp_tcp_new() altcp_tcp_new_ip_type(IPADDR_TYPE_V4)
#define altcp_tcp_new_ip6() altcp_tcp_new_ip_type(IPADDR_TYPE_V6)
struct altcp_pcb *altcp_tcp_alloc(void *arg, u8_t ip_type);
struct tcp_pcb;
struct altcp_pcb *altcp_tcp_wrap(struct tcp_pcb *tpcb);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_TCP_H */
@@ -0,0 +1,117 @@
/**
* @file
* Application layered TCP/TLS connection API (to be used from TCPIP thread)
*
* @defgroup altcp_tls TLS layer
* @ingroup altcp
* This file contains function prototypes for a TLS layer.
* A port to ARM mbedtls is provided in the apps/ tree
* (LWIP_ALTCP_TLS_MBEDTLS option).
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_TLS_H
#define LWIP_HDR_ALTCP_TLS_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#if LWIP_ALTCP_TLS
#include "lwip/altcp.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @ingroup altcp_tls
* ALTCP_TLS configuration handle, content depends on port (e.g. mbedtls)
*/
struct altcp_tls_config;
/** @ingroup altcp_tls
* Create an ALTCP_TLS server configuration handle
*/
struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Create an ALTCP_TLS client configuration handle
*/
struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Create an ALTCP_TLS client configuration handle with two-way server/client authentication
*/
struct altcp_tls_config *altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Free an ALTCP_TLS configuration handle
*/
void altcp_tls_free_config(struct altcp_tls_config *conf);
/** @ingroup altcp_tls
* Create new ALTCP_TLS layer wrapping an existing pcb as inner connection (e.g. TLS over TCP)
*/
struct altcp_pcb *altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb);
/** @ingroup altcp_tls
* Create new ALTCP_TLS pcb and its inner tcp pcb
*/
struct altcp_pcb *altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type);
/** @ingroup altcp_tls
* Create new ALTCP_TLS layer pcb and its inner tcp pcb.
* Same as @ref altcp_tls_new but this allocator function fits to
* @ref altcp_allocator_t / @ref altcp_new.\n
'arg' must contain a struct altcp_tls_config *.
*/
struct altcp_pcb *altcp_tls_alloc(void *arg, u8_t ip_type);
/** @ingroup altcp_tls
* Return pointer to internal TLS context so application can tweak it.
* Real type depends on port (e.g. mbedtls)
*/
void *altcp_tls_context(struct altcp_pcb *conn);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ALTCP_TLS */
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_TLS_H */
@@ -0,0 +1,431 @@
/**
* @file
* netconn API (to be used from non-TCPIP threads)
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_API_H
#define LWIP_HDR_API_H
#include "lwip/opt.h"
#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
/* Note: Netconn API is always available when sockets are enabled -
* sockets are implemented on top of them */
#include "lwip/arch.h"
#include "lwip/netbuf.h"
#include "lwip/sys.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Throughout this file, IP addresses and port numbers are expected to be in
* the same byte order as in the corresponding pcb.
*/
/* Flags for netconn_write (u8_t) */
#define NETCONN_NOFLAG 0x00
#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */
#define NETCONN_COPY 0x01
#define NETCONN_MORE 0x02
#define NETCONN_DONTBLOCK 0x04
#define NETCONN_NOAUTORCVD 0x08 /* prevent netconn_recv_data_tcp() from updating the tcp window - must be done manually via netconn_tcp_recvd() */
#define NETCONN_NOFIN 0x10 /* upper layer already received data, leave FIN in queue until called again */
/* Flags for struct netconn.flags (u8_t) */
/** This netconn had an error, don't block on recvmbox/acceptmbox any more */
#define NETCONN_FLAG_MBOXCLOSED 0x01
/** Should this netconn avoid blocking? */
#define NETCONN_FLAG_NON_BLOCKING 0x02
/** Was the last connect action a non-blocking one? */
#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04
#if LWIP_NETCONN_FULLDUPLEX
/** The mbox of this netconn is being deallocated, don't use it anymore */
#define NETCONN_FLAG_MBOXINVALID 0x08
#endif /* LWIP_NETCONN_FULLDUPLEX */
/** If a nonblocking write has been rejected before, poll_tcp needs to
check if the netconn is writable again */
#define NETCONN_FLAG_CHECK_WRITESPACE 0x10
#if LWIP_IPV6
/** If this flag is set then only IPv6 communication is allowed on the
netconn. As per RFC#3493 this features defaults to OFF allowing
dual-stack usage by default. */
#define NETCONN_FLAG_IPV6_V6ONLY 0x20
#endif /* LWIP_IPV6 */
#if LWIP_NETBUF_RECVINFO
/** Received packet info will be recorded for this netconn */
#define NETCONN_FLAG_PKTINFO 0x40
#endif /* LWIP_NETBUF_RECVINFO */
/** A FIN has been received but not passed to the application yet */
#define NETCONN_FIN_RX_PENDING 0x80
/* Helpers to process several netconn_types by the same code */
#define NETCONNTYPE_GROUP(t) ((t)&0xF0)
#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0)
#if LWIP_IPV6
#define NETCONN_TYPE_IPV6 0x08
#define NETCONNTYPE_ISIPV6(t) (((t)&NETCONN_TYPE_IPV6) != 0)
#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF3) == NETCONN_UDPLITE)
#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM)
#else /* LWIP_IPV6 */
#define NETCONNTYPE_ISIPV6(t) (0)
#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE)
#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM)
#endif /* LWIP_IPV6 */
/** @ingroup netconn_common
* Protocol family and type of the netconn
*/
enum netconn_type {
NETCONN_INVALID = 0,
/** TCP IPv4 */
NETCONN_TCP = 0x10,
#if LWIP_IPV6
/** TCP IPv6 */
NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */,
#endif /* LWIP_IPV6 */
/** UDP IPv4 */
NETCONN_UDP = 0x20,
/** UDP IPv4 lite */
NETCONN_UDPLITE = 0x21,
/** UDP IPv4 no checksum */
NETCONN_UDPNOCHKSUM = 0x22,
#if LWIP_IPV6
/** UDP IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */,
/** UDP IPv6 lite (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */,
/** UDP IPv6 no checksum (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */,
#endif /* LWIP_IPV6 */
/** Raw connection IPv4 */
NETCONN_RAW = 0x40
#if LWIP_IPV6
/** Raw connection IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
, NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */
#endif /* LWIP_IPV6 */
};
/** Current state of the netconn. Non-TCP netconns are always
* in state NETCONN_NONE! */
enum netconn_state {
NETCONN_NONE,
NETCONN_WRITE,
NETCONN_LISTEN,
NETCONN_CONNECT,
NETCONN_CLOSE
};
/** Used to inform the callback function about changes
*
* Event explanation:
*
* In the netconn implementation, there are three ways to block a client:
*
* - accept mbox (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0); in netconn_accept())
* - receive mbox (sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); in netconn_recv_data())
* - send queue is full (sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); in lwip_netconn_do_write())
*
* The events have to be seen as events signaling the state of these mboxes/semaphores. For non-blocking
* connections, you need to know in advance whether a call to a netconn function call would block or not,
* and these events tell you about that.
*
* RCVPLUS events say: Safe to perform a potentially blocking call call once more.
* They are counted in sockets - three RCVPLUS events for accept mbox means you are safe
* to call netconn_accept 3 times without being blocked.
* Same thing for receive mbox.
*
* RCVMINUS events say: Your call to to a possibly blocking function is "acknowledged".
* Socket implementation decrements the counter.
*
* For TX, there is no need to count, its merely a flag. SENDPLUS means you may send something.
* SENDPLUS occurs when enough data was delivered to peer so netconn_send() can be called again.
* A SENDMINUS event occurs when the next call to a netconn_send() would be blocking.
*/
enum netconn_evt {
NETCONN_EVT_RCVPLUS,
NETCONN_EVT_RCVMINUS,
NETCONN_EVT_SENDPLUS,
NETCONN_EVT_SENDMINUS,
NETCONN_EVT_ERROR
};
#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
/** Used for netconn_join_leave_group() */
enum netconn_igmp {
NETCONN_JOIN,
NETCONN_LEAVE
};
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
#if LWIP_DNS
/* Used for netconn_gethostbyname_addrtype(), these should match the DNS_ADDRTYPE defines in dns.h */
#define NETCONN_DNS_DEFAULT NETCONN_DNS_IPV4_IPV6
#define NETCONN_DNS_IPV4 0
#define NETCONN_DNS_IPV6 1
#define NETCONN_DNS_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */
#define NETCONN_DNS_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */
#endif /* LWIP_DNS */
/* forward-declare some structs to avoid to include their headers */
struct ip_pcb;
struct tcp_pcb;
struct udp_pcb;
struct raw_pcb;
struct netconn;
struct api_msg;
/** A callback prototype to inform about events for a netconn */
typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len);
/** A netconn descriptor */
struct netconn {
/** type of the netconn (TCP, UDP or RAW) */
enum netconn_type type;
/** current state of the netconn */
enum netconn_state state;
/** the lwIP internal protocol control block */
union {
struct ip_pcb *ip;
struct tcp_pcb *tcp;
struct udp_pcb *udp;
struct raw_pcb *raw;
} pcb;
/** the last asynchronous unreported error this netconn had */
err_t pending_err;
#if !LWIP_NETCONN_SEM_PER_THREAD
/** sem that is used to synchronously execute functions in the core context */
sys_sem_t op_completed;
#endif
/** mbox where received packets are stored until they are fetched
by the netconn application thread (can grow quite big) */
sys_mbox_t recvmbox;
#if LWIP_TCP
/** mbox where new connections are stored until processed
by the application thread */
sys_mbox_t acceptmbox;
#endif /* LWIP_TCP */
#if LWIP_NETCONN_FULLDUPLEX
/** number of threads waiting on an mbox. This is required to unblock
all threads when closing while threads are waiting. */
int mbox_threads_waiting;
#endif
/** only used for socket layer */
#if LWIP_SOCKET
int socket;
#endif /* LWIP_SOCKET */
#if LWIP_SO_SNDTIMEO
/** timeout to wait for sending data (which means enqueueing data for sending
in internal buffers) in milliseconds */
s32_t send_timeout;
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVTIMEO
/** timeout in milliseconds to wait for new data to be received
(or connections to arrive for listening netconns) */
u32_t recv_timeout;
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVBUF
/** maximum amount of bytes queued in recvmbox
not used for TCP: adjust TCP_WND instead! */
int recv_bufsize;
/** number of bytes currently in recvmbox to be received,
tested against recv_bufsize to limit bytes on recvmbox
for UDP and RAW, used for FIONREAD */
int recv_avail;
#endif /* LWIP_SO_RCVBUF */
#if LWIP_SO_LINGER
/** values <0 mean linger is disabled, values > 0 are seconds to linger */
s16_t linger;
#endif /* LWIP_SO_LINGER */
/** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
u8_t flags;
#if LWIP_TCP
/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
this temporarily stores the message.
Also used during connect and close. */
struct api_msg *current_msg;
#endif /* LWIP_TCP */
/** A callback function that is informed about events for this netconn */
netconn_callback callback;
};
/** This vector type is passed to @ref netconn_write_vectors_partly to send
* multiple buffers at once.
* ATTENTION: This type has to directly map struct iovec since one is casted
* into the other!
*/
struct netvector {
/** pointer to the application buffer that contains the data to send */
const void *ptr;
/** size of the application data to send */
size_t len;
};
/** Register an Network connection event */
#define API_EVENT(c,e,l) if (c->callback) { \
(*c->callback)(c, e, l); \
}
/* Network connection functions: */
/** @ingroup netconn_common
* Create new netconn connection
* @param t @ref netconn_type */
#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL)
#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c)
struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto,
netconn_callback callback);
err_t netconn_prepare_delete(struct netconn *conn);
err_t netconn_delete(struct netconn *conn);
/** Get the type of a netconn (as enum netconn_type). */
#define netconn_type(conn) (conn->type)
err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr,
u16_t *port, u8_t local);
/** @ingroup netconn_common */
#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0)
/** @ingroup netconn_common */
#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1)
err_t netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port);
err_t netconn_bind_if(struct netconn *conn, u8_t if_idx);
err_t netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port);
err_t netconn_disconnect (struct netconn *conn);
err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
/** @ingroup netconn_tcp */
#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG)
err_t netconn_accept(struct netconn *conn, struct netconn **new_conn);
err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf);
err_t netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf);
err_t netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags);
err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf);
err_t netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags);
err_t netconn_tcp_recvd(struct netconn *conn, size_t len);
err_t netconn_sendto(struct netconn *conn, struct netbuf *buf,
const ip_addr_t *addr, u16_t port);
err_t netconn_send(struct netconn *conn, struct netbuf *buf);
err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
u8_t apiflags, size_t *bytes_written);
err_t netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt,
u8_t apiflags, size_t *bytes_written);
/** @ingroup netconn_tcp */
#define netconn_write(conn, dataptr, size, apiflags) \
netconn_write_partly(conn, dataptr, size, apiflags, NULL)
err_t netconn_close(struct netconn *conn);
err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx);
#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
err_t netconn_join_leave_group(struct netconn *conn, const ip_addr_t *multiaddr,
const ip_addr_t *netif_addr, enum netconn_igmp join_or_leave);
err_t netconn_join_leave_group_netif(struct netconn *conn, const ip_addr_t *multiaddr,
u8_t if_idx, enum netconn_igmp join_or_leave);
#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
#if LWIP_DNS
#if LWIP_IPV4 && LWIP_IPV6
err_t netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype);
#define netconn_gethostbyname(name, addr) netconn_gethostbyname_addrtype(name, addr, NETCONN_DNS_DEFAULT)
#else /* LWIP_IPV4 && LWIP_IPV6 */
err_t netconn_gethostbyname(const char *name, ip_addr_t *addr);
#define netconn_gethostbyname_addrtype(name, addr, dns_addrtype) netconn_gethostbyname(name, addr)
#endif /* LWIP_IPV4 && LWIP_IPV6 */
#endif /* LWIP_DNS */
err_t netconn_err(struct netconn *conn);
#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize)
#define netconn_set_flags(conn, set_flags) do { (conn)->flags = (u8_t)((conn)->flags | (set_flags)); } while(0)
#define netconn_clear_flags(conn, clr_flags) do { (conn)->flags = (u8_t)((conn)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
#define netconn_is_flag_set(conn, flag) (((conn)->flags & (flag)) != 0)
/** Set the blocking status of netconn calls (@todo: write/send is missing) */
#define netconn_set_nonblocking(conn, val) do { if(val) { \
netconn_set_flags(conn, NETCONN_FLAG_NON_BLOCKING); \
} else { \
netconn_clear_flags(conn, NETCONN_FLAG_NON_BLOCKING); }} while(0)
/** Get the blocking status of netconn calls (@todo: write/send is missing) */
#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0)
#if LWIP_IPV6
/** @ingroup netconn_common
* TCP: Set the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY)
*/
#define netconn_set_ipv6only(conn, val) do { if(val) { \
netconn_set_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); \
} else { \
netconn_clear_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); }} while(0)
/** @ingroup netconn_common
* TCP: Get the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY)
*/
#define netconn_get_ipv6only(conn) (((conn)->flags & NETCONN_FLAG_IPV6_V6ONLY) != 0)
#endif /* LWIP_IPV6 */
#if LWIP_SO_SNDTIMEO
/** Set the send timeout in milliseconds */
#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout))
/** Get the send timeout in milliseconds */
#define netconn_get_sendtimeout(conn) ((conn)->send_timeout)
#endif /* LWIP_SO_SNDTIMEO */
#if LWIP_SO_RCVTIMEO
/** Set the receive timeout in milliseconds */
#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout))
/** Get the receive timeout in milliseconds */
#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout)
#endif /* LWIP_SO_RCVTIMEO */
#if LWIP_SO_RCVBUF
/** Set the receive buffer in bytes */
#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize))
/** Get the receive buffer in bytes */
#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize)
#endif /* LWIP_SO_RCVBUF*/
#if LWIP_NETCONN_SEM_PER_THREAD
void netconn_thread_init(void);
void netconn_thread_cleanup(void);
#else /* LWIP_NETCONN_SEM_PER_THREAD */
#define netconn_thread_init()
#define netconn_thread_cleanup()
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_NETCONN || LWIP_SOCKET */
#endif /* LWIP_HDR_API_H */
@@ -0,0 +1,79 @@
/**
* @file
* Application layered TCP connection API that executes a proxy-connect.
*
* This file provides a starting layer that executes a proxy-connect e.g. to
* set up TLS connections through a http proxy.
*/
/*
* Copyright (c) 2018 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H
#define LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
struct altcp_proxyconnect_config {
ip_addr_t proxy_addr;
u16_t proxy_port;
};
struct altcp_pcb *altcp_proxyconnect_new(struct altcp_proxyconnect_config *config, struct altcp_pcb *inner_pcb);
struct altcp_pcb *altcp_proxyconnect_new_tcp(struct altcp_proxyconnect_config *config, u8_t ip_type);
struct altcp_pcb *altcp_proxyconnect_alloc(void *arg, u8_t ip_type);
#if LWIP_ALTCP_TLS
struct altcp_proxyconnect_tls_config {
struct altcp_proxyconnect_config proxy;
struct altcp_tls_config *tls_config;
};
struct altcp_pcb *altcp_proxyconnect_tls_alloc(void *arg, u8_t ip_type);
#endif /* LWIP_ALTCP_TLS */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H */
@@ -0,0 +1,67 @@
/**
* @file
* Application layered TCP/TLS connection API (to be used from TCPIP thread)
*
* This file contains options for an mbedtls port of the TLS layer.
*/
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_ALTCP_TLS_OPTS_H
#define LWIP_HDR_ALTCP_TLS_OPTS_H
#include "lwip/opt.h"
#if LWIP_ALTCP /* don't build if not configured for use in lwipopts.h */
/** LWIP_ALTCP_TLS_MBEDTLS==1: use mbedTLS for TLS support for altcp API
* mbedtls include directory must be reachable via include search path
*/
#ifndef LWIP_ALTCP_TLS_MBEDTLS
#define LWIP_ALTCP_TLS_MBEDTLS 0
#endif
/** Configure debug level of this file */
#ifndef ALTCP_MBEDTLS_DEBUG
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_OFF
#endif
/** Set a session timeout in seconds for the basic session cache
* ATTENTION: Using a session cache can lower security by reusing keys!
*/
#ifndef ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS 0
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_ALTCP_TLS_OPTS_H */
@@ -0,0 +1,126 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_APPS_FS_H
#define LWIP_HDR_APPS_FS_H
#include "httpd_opts.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FS_READ_EOF -1
#define FS_READ_DELAYED -2
#if HTTPD_PRECALCULATED_CHECKSUM
struct fsdata_chksum {
u32_t offset;
u16_t chksum;
u16_t len;
};
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
#define FS_FILE_FLAGS_HEADER_INCLUDED 0x01
#define FS_FILE_FLAGS_HEADER_PERSISTENT 0x02
#define FS_FILE_FLAGS_HEADER_HTTPVER_1_1 0x04
#define FS_FILE_FLAGS_SSI 0x08
/** Define FS_FILE_EXTENSION_T_DEFINED if you have typedef'ed to your private
* pointer type (defaults to 'void' so the default usage is 'void*')
*/
#ifndef FS_FILE_EXTENSION_T_DEFINED
typedef void fs_file_extension;
#endif
struct fs_file {
const char *data;
int len;
int index;
/* pextension is free for implementations to hold private (extensional)
arbitrary data, e.g. holding some file state or file system handle */
fs_file_extension *pextension;
#if HTTPD_PRECALCULATED_CHECKSUM
const struct fsdata_chksum *chksum;
u16_t chksum_count;
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
u8_t flags;
#if LWIP_HTTPD_CUSTOM_FILES
u8_t is_custom_file;
#endif /* LWIP_HTTPD_CUSTOM_FILES */
#if LWIP_HTTPD_FILE_STATE
void *state;
#endif /* LWIP_HTTPD_FILE_STATE */
};
#if LWIP_HTTPD_FS_ASYNC_READ
typedef void (*fs_wait_cb)(void *arg);
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
err_t fs_open(struct fs_file *file, const char *name);
void fs_close(struct fs_file *file);
#if LWIP_HTTPD_DYNAMIC_FILE_READ
#if LWIP_HTTPD_FS_ASYNC_READ
int fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg);
#else /* LWIP_HTTPD_FS_ASYNC_READ */
int fs_read(struct fs_file *file, char *buffer, int count);
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
#if LWIP_HTTPD_FS_ASYNC_READ
int fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg);
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
int fs_bytes_left(struct fs_file *file);
#if LWIP_HTTPD_FILE_STATE
/** This user-defined function is called when a file is opened. */
void *fs_state_init(struct fs_file *file, const char *name);
/** This user-defined function is called when a file is closed. */
void fs_state_free(struct fs_file *file, void *state);
#endif /* #if LWIP_HTTPD_FILE_STATE */
struct fsdata_file {
const struct fsdata_file *next;
const unsigned char *name;
const unsigned char *data;
int len;
u8_t flags;
#if HTTPD_PRECALCULATED_CHECKSUM
u16_t chksum_count;
const struct fsdata_chksum *chksum;
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
};
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_FS_H */
@@ -0,0 +1,160 @@
/**
* @file
* HTTP client
*/
/*
* Copyright (c) 2018 Simon Goldschmidt <goldsimon@gmx.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
#ifndef LWIP_HDR_APPS_HTTP_CLIENT_H
#define LWIP_HDR_APPS_HTTP_CLIENT_H
#include "lwip/opt.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#include "lwip/altcp.h"
#include "lwip/prot/iana.h"
#include "lwip/pbuf.h"
#if LWIP_TCP && LWIP_CALLBACK_API
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup httpc
* HTTPC_HAVE_FILE_IO: define this to 1 to have functions dowloading directly
* to disk via fopen/fwrite.
* These functions are example implementations of the interface only.
*/
#ifndef LWIP_HTTPC_HAVE_FILE_IO
#define LWIP_HTTPC_HAVE_FILE_IO 0
#endif
/**
* @ingroup httpc
* The default TCP port used for HTTP
*/
#define HTTP_DEFAULT_PORT LWIP_IANA_PORT_HTTP
/**
* @ingroup httpc
* HTTP client result codes
*/
typedef enum ehttpc_result {
/** File successfully received */
HTTPC_RESULT_OK = 0,
/** Unknown error */
HTTPC_RESULT_ERR_UNKNOWN = 1,
/** Connection to server failed */
HTTPC_RESULT_ERR_CONNECT = 2,
/** Failed to resolve server hostname */
HTTPC_RESULT_ERR_HOSTNAME = 3,
/** Connection unexpectedly closed by remote server */
HTTPC_RESULT_ERR_CLOSED = 4,
/** Connection timed out (server didn't respond in time) */
HTTPC_RESULT_ERR_TIMEOUT = 5,
/** Server responded with an error code */
HTTPC_RESULT_ERR_SVR_RESP = 6,
/** Local memory error */
HTTPC_RESULT_ERR_MEM = 7,
/** Local abort */
HTTPC_RESULT_LOCAL_ABORT = 8,
/** Content length mismatch */
HTTPC_RESULT_ERR_CONTENT_LEN = 9
} httpc_result_t;
typedef struct _httpc_state httpc_state_t;
/**
* @ingroup httpc
* Prototype of a http client callback function
*
* @param arg argument specified when initiating the request
* @param httpc_result result of the http transfer (see enum httpc_result_t)
* @param rx_content_len number of bytes received (without headers)
* @param srv_res this contains the http status code received (if any)
* @param err an error returned by internal lwip functions, can help to specify
* the source of the error but must not necessarily be != ERR_OK
*/
typedef void (*httpc_result_fn)(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err);
/**
* @ingroup httpc
* Prototype of http client callback: called when the headers are received
*
* @param connection http client connection
* @param arg argument specified when initiating the request
* @param hdr header pbuf(s) (may contain data also)
* @param hdr_len length of the heders in 'hdr'
* @param content_len content length as received in the headers (-1 if not received)
* @return if != ERR_OK is returned, the connection is aborted
*/
typedef err_t (*httpc_headers_done_fn)(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len);
typedef struct _httpc_connection {
ip_addr_t proxy_addr;
u16_t proxy_port;
u8_t use_proxy;
/* @todo: add username:pass? */
#if LWIP_ALTCP
altcp_allocator_t *altcp_allocator;
#endif
/* this callback is called when the transfer is finished (or aborted) */
httpc_result_fn result_fn;
/* this callback is called after receiving the http headers
It can abort the connection by returning != ERR_OK */
httpc_headers_done_fn headers_done_fn;
} httpc_connection_t;
err_t httpc_get_file(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings,
altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection);
err_t httpc_get_file_dns(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings,
altcp_recv_fn recv_fn, void* callback_arg, httpc_state_t **connection);
#if LWIP_HTTPC_HAVE_FILE_IO
err_t httpc_get_file_to_disk(const ip_addr_t* server_addr, u16_t port, const char* uri, const httpc_connection_t *settings,
void* callback_arg, const char* local_file_name, httpc_state_t **connection);
err_t httpc_get_file_dns_to_disk(const char* server_name, u16_t port, const char* uri, const httpc_connection_t *settings,
void* callback_arg, const char* local_file_name, httpc_state_t **connection);
#endif /* LWIP_HTTPC_HAVE_FILE_IO */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_TCP && LWIP_CALLBACK_API */
#endif /* LWIP_HDR_APPS_HTTP_CLIENT_H */
@@ -0,0 +1,255 @@
/**
* @file
* HTTP server
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* This version of the file has been modified by Texas Instruments to offer
* simple server-side-include (SSI) and Common Gateway Interface (CGI)
* capability.
*/
#ifndef LWIP_HDR_APPS_HTTPD_H
#define LWIP_HDR_APPS_HTTPD_H
#include "httpd_opts.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_HTTPD_CGI
/**
* @ingroup httpd
* Function pointer for a CGI script handler.
*
* This function is called each time the HTTPD server is asked for a file
* whose name was previously registered as a CGI function using a call to
* http_set_cgi_handlers. The iIndex parameter provides the index of the
* CGI within the cgis array passed to http_set_cgi_handlers. Parameters
* pcParam and pcValue provide access to the parameters provided along with
* the URI. iNumParams provides a count of the entries in the pcParam and
* pcValue arrays. Each entry in the pcParam array contains the name of a
* parameter with the corresponding entry in the pcValue array containing the
* value for that parameter. Note that pcParam may contain multiple elements
* with the same name if, for example, a multi-selection list control is used
* in the form generating the data.
*
* The function should return a pointer to a character string which is the
* path and filename of the response that is to be sent to the connected
* browser, for example "/thanks.htm" or "/response/error.ssi".
*
* The maximum number of parameters that will be passed to this function via
* iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in
* the incoming HTTP request above this number will be discarded.
*
* Requests intended for use by this CGI mechanism must be sent using the GET
* method (which encodes all parameters within the URI rather than in a block
* later in the request). Attempts to use the POST method will result in the
* request being ignored.
*
*/
typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[],
char *pcValue[]);
/**
* @ingroup httpd
* Structure defining the base filename (URL) of a CGI and the associated
* function which is to be called when that URL is requested.
*/
typedef struct
{
const char *pcCGIName;
tCGIHandler pfnCGIHandler;
} tCGI;
void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers);
#endif /* LWIP_HTTPD_CGI */
#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI
#if LWIP_HTTPD_CGI_SSI
/* we have to prototype this struct here to make it available for the handler */
struct fs_file;
/** Define this generic CGI handler in your application.
* It is called once for every URI with parameters.
* The parameters can be stored to the object passed as connection_state, which
* is allocated to file->state via fs_state_init() from fs_open() or fs_open_custom().
* Content creation via SSI or complete dynamic files can retrieve the CGI params from there.
*/
extern void httpd_cgi_handler(struct fs_file *file, const char* uri, int iNumParams,
char **pcParam, char **pcValue
#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
, void *connection_state
#endif /* LWIP_HTTPD_FILE_STATE */
);
#endif /* LWIP_HTTPD_CGI_SSI */
#endif /* LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI */
#if LWIP_HTTPD_SSI
/**
* @ingroup httpd
* Function pointer for the SSI tag handler callback.
*
* This function will be called each time the HTTPD server detects a tag of the
* form <!--#name--> in files with extensions mentioned in the g_pcSSIExtensions
* array (currently .shtml, .shtm, .ssi, .xml, .json) where "name" appears as
* one of the tags supplied to http_set_ssi_handler in the tags array. The
* returned insert string, which will be appended after the the string
* "<!--#name-->" in file sent back to the client, should be written to pointer
* pcInsert. iInsertLen contains the size of the buffer pointed to by
* pcInsert. The iIndex parameter provides the zero-based index of the tag as
* found in the tags array and identifies the tag that is to be processed.
*
* The handler returns the number of characters written to pcInsert excluding
* any terminating NULL or HTTPD_SSI_TAG_UNKNOWN when tag is not recognized.
*
* Note that the behavior of this SSI mechanism is somewhat different from the
* "normal" SSI processing as found in, for example, the Apache web server. In
* this case, the inserted text is appended following the SSI tag rather than
* replacing the tag entirely. This allows for an implementation that does not
* require significant additional buffering of output data yet which will still
* offer usable SSI functionality. One downside to this approach is when
* attempting to use SSI within JavaScript. The SSI tag is structured to
* resemble an HTML comment but this syntax does not constitute a comment
* within JavaScript and, hence, leaving the tag in place will result in
* problems in these cases. In order to avoid these problems, define
* LWIP_HTTPD_SSI_INCLUDE_TAG as zero in your lwip options file, or use JavaScript
* style block comments in the form / * # name * / (without the spaces).
*/
typedef u16_t (*tSSIHandler)(
#if LWIP_HTTPD_SSI_RAW
const char* ssi_tag_name,
#else /* LWIP_HTTPD_SSI_RAW */
int iIndex,
#endif /* LWIP_HTTPD_SSI_RAW */
char *pcInsert, int iInsertLen
#if LWIP_HTTPD_SSI_MULTIPART
, u16_t current_tag_part, u16_t *next_tag_part
#endif /* LWIP_HTTPD_SSI_MULTIPART */
#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE
, void *connection_state
#endif /* LWIP_HTTPD_FILE_STATE */
);
/** Set the SSI handler function
* (if LWIP_HTTPD_SSI_RAW==1, only the first argument is used)
*/
void http_set_ssi_handler(tSSIHandler pfnSSIHandler,
const char **ppcTags, int iNumTags);
/** For LWIP_HTTPD_SSI_RAW==1, return this to indicate the tag is unknown.
* In this case, the webserver writes a warning into the page.
* You can also just return 0 to write nothing for unknown tags.
*/
#define HTTPD_SSI_TAG_UNKNOWN 0xFFFF
#endif /* LWIP_HTTPD_SSI */
#if LWIP_HTTPD_SUPPORT_POST
/* These functions must be implemented by the application */
/**
* @ingroup httpd
* Called when a POST request has been received. The application can decide
* whether to accept it or not.
*
* @param connection Unique connection identifier, valid until httpd_post_end
* is called.
* @param uri The HTTP header URI receiving the POST request.
* @param http_request The raw HTTP request (the first packet, normally).
* @param http_request_len Size of 'http_request'.
* @param content_len Content-Length from HTTP header.
* @param response_uri Filename of response file, to be filled when denying the
* request
* @param response_uri_len Size of the 'response_uri' buffer.
* @param post_auto_wnd Set this to 0 to let the callback code handle window
* updates by calling 'httpd_post_data_recved' (to throttle rx speed)
* default is 1 (httpd handles window updates automatically)
* @return ERR_OK: Accept the POST request, data may be passed in
* another err_t: Deny the POST request, send back 'bad request'.
*/
err_t httpd_post_begin(void *connection, const char *uri, const char *http_request,
u16_t http_request_len, int content_len, char *response_uri,
u16_t response_uri_len, u8_t *post_auto_wnd);
/**
* @ingroup httpd
* Called for each pbuf of data that has been received for a POST.
* ATTENTION: The application is responsible for freeing the pbufs passed in!
*
* @param connection Unique connection identifier.
* @param p Received data.
* @return ERR_OK: Data accepted.
* another err_t: Data denied, http_post_get_response_uri will be called.
*/
err_t httpd_post_receive_data(void *connection, struct pbuf *p);
/**
* @ingroup httpd
* Called when all data is received or when the connection is closed.
* The application must return the filename/URI of a file to send in response
* to this POST request. If the response_uri buffer is untouched, a 404
* response is returned.
*
* @param connection Unique connection identifier.
* @param response_uri Filename of response file, to be filled when denying the request
* @param response_uri_len Size of the 'response_uri' buffer.
*/
void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len);
#if LWIP_HTTPD_POST_MANUAL_WND
void httpd_post_data_recved(void *connection, u16_t recved_len);
#endif /* LWIP_HTTPD_POST_MANUAL_WND */
#endif /* LWIP_HTTPD_SUPPORT_POST */
void httpd_init(void);
#if HTTPD_ENABLE_HTTPS
struct altcp_tls_config;
void httpd_inits(struct altcp_tls_config *conf);
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_HTTPD_H */
@@ -0,0 +1,396 @@
/**
* @file
* HTTP server options list
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* This version of the file has been modified by Texas Instruments to offer
* simple server-side-include (SSI) and Common Gateway Interface (CGI)
* capability.
*/
#ifndef LWIP_HDR_APPS_HTTPD_OPTS_H
#define LWIP_HDR_APPS_HTTPD_OPTS_H
#include "lwip/opt.h"
#include "lwip/prot/iana.h"
/**
* @defgroup httpd_opts Options
* @ingroup httpd
* @{
*/
/** Set this to 1 to support CGI (old style).
*
* This old style CGI support works by registering an array of URLs and
* associated CGI handler functions (@ref http_set_cgi_handlers).
* This list is scanned just before fs_open is called from request handling.
* The handler can return a new URL that is used internally by the httpd to
* load the returned page (passed to fs_open).
*
* Use this CGI type e.g. to execute specific actions and return a page that
* does not depend on the CGI parameters.
*/
#if !defined LWIP_HTTPD_CGI || defined __DOXYGEN__
#define LWIP_HTTPD_CGI 0
#endif
/** Set this to 1 to support CGI (new style).
*
* This new style CGI support works by calling a global function
* (@ref tCGIHandler) for all URLs that are found. fs_open is called first
* and the URL can not be written by the CGI handler. Instead, this handler gets
* passed the http file state, an object where it can store information derived
* from the CGI URL or parameters. This file state is later passed to SSI, so
* the SSI code can return data depending on CGI input.
*
* Use this CGI handler if you want CGI information passed on to SSI.
*/
#if !defined LWIP_HTTPD_CGI_SSI || defined __DOXYGEN__
#define LWIP_HTTPD_CGI_SSI 0
#endif
/** Set this to 1 to support SSI (Server-Side-Includes)
*
* In contrast to other http servers, this only calls a preregistered callback
* function (@see http_set_ssi_handler) for each tag (in the format of
* <!--#tag-->) encountered in SSI-enabled pages.
* SSI-enabled pages must have one of the predefined SSI-enabled file extensions.
* All files with one of these extensions are parsed when sent.
*
* A downside of the current SSI implementation is that persistent connections
* don't work, as the file length is not known in advance (and httpd currently
* relies on the Content-Length header for persistent connections).
*
* To save memory, the maximum tag length is limited (@see LWIP_HTTPD_MAX_TAG_NAME_LEN).
* To save memory, the maximum insertion string length is limited (@see
* LWIP_HTTPD_MAX_TAG_INSERT_LEN). If this is not enought, @ref LWIP_HTTPD_SSI_MULTIPART
* can be used.
*/
#if !defined LWIP_HTTPD_SSI || defined __DOXYGEN__
#define LWIP_HTTPD_SSI 0
#endif
/** Set this to 1 to implement an SSI tag handler callback that gets a const char*
* to the tag (instead of an index into a pre-registered array of known tags)
* If this is 0, the SSI handler callback function is only called pre-registered tags.
*/
#if !defined LWIP_HTTPD_SSI_RAW || defined __DOXYGEN__
#define LWIP_HTTPD_SSI_RAW 0
#endif
/** Set this to 0 to prevent parsing the file extension at runtime to decide
* if a file should be scanned for SSI tags or not.
* Default is 1 (file extensions are checked using the g_pcSSIExtensions array)
* Set to 2 to override this runtime test function.
*
* This is enabled by default, but if you only use a newer version of makefsdata
* supporting the "-ssi" option, this info is already present in
*/
#if !defined LWIP_HTTPD_SSI_BY_FILE_EXTENSION || defined __DOXYGEN__
#define LWIP_HTTPD_SSI_BY_FILE_EXTENSION 1
#endif
/** Set this to 1 to support HTTP POST */
#if !defined LWIP_HTTPD_SUPPORT_POST || defined __DOXYGEN__
#define LWIP_HTTPD_SUPPORT_POST 0
#endif
/* The maximum number of parameters that the CGI handler can be sent. */
#if !defined LWIP_HTTPD_MAX_CGI_PARAMETERS || defined __DOXYGEN__
#define LWIP_HTTPD_MAX_CGI_PARAMETERS 16
#endif
/** LWIP_HTTPD_SSI_MULTIPART==1: SSI handler function is called with 2 more
* arguments indicating a counter for insert string that are too long to be
* inserted at once: the SSI handler function must then set 'next_tag_part'
* which will be passed back to it in the next call. */
#if !defined LWIP_HTTPD_SSI_MULTIPART || defined __DOXYGEN__
#define LWIP_HTTPD_SSI_MULTIPART 0
#endif
/* The maximum length of the string comprising the SSI tag name
* ATTENTION: tags longer than this are ignored, not truncated!
*/
#if !defined LWIP_HTTPD_MAX_TAG_NAME_LEN || defined __DOXYGEN__
#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8
#endif
/* The maximum length of string that can be returned to replace any given tag
* If this buffer is not long enough, use LWIP_HTTPD_SSI_MULTIPART.
*/
#if !defined LWIP_HTTPD_MAX_TAG_INSERT_LEN || defined __DOXYGEN__
#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192
#endif
#if !defined LWIP_HTTPD_POST_MANUAL_WND || defined __DOXYGEN__
#define LWIP_HTTPD_POST_MANUAL_WND 0
#endif
/** This string is passed in the HTTP header as "Server: " */
#if !defined HTTPD_SERVER_AGENT || defined __DOXYGEN__
#define HTTPD_SERVER_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)"
#endif
/** Set this to 1 if you want to include code that creates HTTP headers
* at runtime. Default is off: HTTP headers are then created statically
* by the makefsdata tool. Static headers mean smaller code size, but
* the (readonly) fsdata will grow a bit as every file includes the HTTP
* header. */
#if !defined LWIP_HTTPD_DYNAMIC_HEADERS || defined __DOXYGEN__
#define LWIP_HTTPD_DYNAMIC_HEADERS 0
#endif
#if !defined HTTPD_DEBUG || defined __DOXYGEN__
#define HTTPD_DEBUG LWIP_DBG_OFF
#endif
/** Set this to 1 to use a memp pool for allocating
* struct http_state instead of the heap.
* If enabled, you'll need to define MEMP_NUM_PARALLEL_HTTPD_CONNS
* (and MEMP_NUM_PARALLEL_HTTPD_SSI_CONNS for SSI) to set the size of
* the pool(s).
*/
#if !defined HTTPD_USE_MEM_POOL || defined __DOXYGEN__
#define HTTPD_USE_MEM_POOL 0
#endif
/** The server port for HTTPD to use */
#if !defined HTTPD_SERVER_PORT || defined __DOXYGEN__
#define HTTPD_SERVER_PORT LWIP_IANA_PORT_HTTP
#endif
/** The https server port for HTTPD to use */
#if !defined HTTPD_SERVER_PORT_HTTPS || defined __DOXYGEN__
#define HTTPD_SERVER_PORT_HTTPS LWIP_IANA_PORT_HTTPS
#endif
/** Enable https support? */
#if !defined HTTPD_ENABLE_HTTPS || defined __DOXYGEN__
#define HTTPD_ENABLE_HTTPS 0
#endif
/** Maximum retries before the connection is aborted/closed.
* - number of times pcb->poll is called -> default is 4*500ms = 2s;
* - reset when pcb->sent is called
*/
#if !defined HTTPD_MAX_RETRIES || defined __DOXYGEN__
#define HTTPD_MAX_RETRIES 4
#endif
/** The poll delay is X*500ms */
#if !defined HTTPD_POLL_INTERVAL || defined __DOXYGEN__
#define HTTPD_POLL_INTERVAL 4
#endif
/** Priority for tcp pcbs created by HTTPD (very low by default).
* Lower priorities get killed first when running out of memory.
*/
#if !defined HTTPD_TCP_PRIO || defined __DOXYGEN__
#define HTTPD_TCP_PRIO TCP_PRIO_MIN
#endif
/** Set this to 1 to enable timing each file sent */
#if !defined LWIP_HTTPD_TIMING || defined __DOXYGEN__
#define LWIP_HTTPD_TIMING 0
#endif
/** Set this to 1 to enable timing each file sent */
#if !defined HTTPD_DEBUG_TIMING || defined __DOXYGEN__
#define HTTPD_DEBUG_TIMING LWIP_DBG_OFF
#endif
/** Set this to one to show error pages when parsing a request fails instead
of simply closing the connection. */
#if !defined LWIP_HTTPD_SUPPORT_EXTSTATUS || defined __DOXYGEN__
#define LWIP_HTTPD_SUPPORT_EXTSTATUS 0
#endif
/** Set this to 0 to drop support for HTTP/0.9 clients (to save some bytes) */
#if !defined LWIP_HTTPD_SUPPORT_V09 || defined __DOXYGEN__
#define LWIP_HTTPD_SUPPORT_V09 1
#endif
/** Set this to 1 to enable HTTP/1.1 persistent connections.
* ATTENTION: If the generated file system includes HTTP headers, these must
* include the "Connection: keep-alive" header (pass argument "-11" to makefsdata).
*/
#if !defined LWIP_HTTPD_SUPPORT_11_KEEPALIVE || defined __DOXYGEN__
#define LWIP_HTTPD_SUPPORT_11_KEEPALIVE 0
#endif
/** Set this to 1 to support HTTP request coming in in multiple packets/pbufs */
#if !defined LWIP_HTTPD_SUPPORT_REQUESTLIST || defined __DOXYGEN__
#define LWIP_HTTPD_SUPPORT_REQUESTLIST 1
#endif
#if LWIP_HTTPD_SUPPORT_REQUESTLIST
/** Number of rx pbufs to enqueue to parse an incoming request (up to the first
newline) */
#if !defined LWIP_HTTPD_REQ_QUEUELEN || defined __DOXYGEN__
#define LWIP_HTTPD_REQ_QUEUELEN 5
#endif
/** Number of (TCP payload-) bytes (in pbufs) to enqueue to parse and incoming
request (up to the first double-newline) */
#if !defined LWIP_HTTPD_REQ_BUFSIZE || defined __DOXYGEN__
#define LWIP_HTTPD_REQ_BUFSIZE LWIP_HTTPD_MAX_REQ_LENGTH
#endif
/** Defines the maximum length of a HTTP request line (up to the first CRLF,
copied from pbuf into this a global buffer when pbuf- or packet-queues
are received - otherwise the input pbuf is used directly) */
#if !defined LWIP_HTTPD_MAX_REQ_LENGTH || defined __DOXYGEN__
#define LWIP_HTTPD_MAX_REQ_LENGTH LWIP_MIN(1023, (LWIP_HTTPD_REQ_QUEUELEN * PBUF_POOL_BUFSIZE))
#endif
#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */
/** This is the size of a static buffer used when URIs end with '/'.
* In this buffer, the directory requested is concatenated with all the
* configured default file names.
* Set to 0 to disable checking default filenames on non-root directories.
*/
#if !defined LWIP_HTTPD_MAX_REQUEST_URI_LEN || defined __DOXYGEN__
#define LWIP_HTTPD_MAX_REQUEST_URI_LEN 63
#endif
/** Maximum length of the filename to send as response to a POST request,
* filled in by the application when a POST is finished.
*/
#if !defined LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN || defined __DOXYGEN__
#define LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN 63
#endif
/** Set this to 0 to not send the SSI tag (default is on, so the tag will
* be sent in the HTML page */
#if !defined LWIP_HTTPD_SSI_INCLUDE_TAG || defined __DOXYGEN__
#define LWIP_HTTPD_SSI_INCLUDE_TAG 1
#endif
/** Set this to 1 to call tcp_abort when tcp_close fails with memory error.
* This can be used to prevent consuming all memory in situations where the
* HTTP server has low priority compared to other communication. */
#if !defined LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR || defined __DOXYGEN__
#define LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR 0
#endif
/** Set this to 1 to kill the oldest connection when running out of
* memory for 'struct http_state' or 'struct http_ssi_state'.
* ATTENTION: This puts all connections on a linked list, so may be kind of slow.
*/
#if !defined LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED || defined __DOXYGEN__
#define LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED 0
#endif
/** Set this to 1 to send URIs without extension without headers
* (who uses this at all??) */
#if !defined LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI || defined __DOXYGEN__
#define LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI 0
#endif
/** Default: Tags are sent from struct http_state and are therefore volatile */
#if !defined HTTP_IS_TAG_VOLATILE || defined __DOXYGEN__
#define HTTP_IS_TAG_VOLATILE(ptr) TCP_WRITE_FLAG_COPY
#endif
/* By default, the httpd is limited to send 2*pcb->mss to keep resource usage low
when http is not an important protocol in the device. */
#if !defined HTTPD_LIMIT_SENDING_TO_2MSS || defined __DOXYGEN__
#define HTTPD_LIMIT_SENDING_TO_2MSS 1
#endif
/* Define this to a function that returns the maximum amount of data to enqueue.
The function have this signature: u16_t fn(struct altcp_pcb* pcb);
The best place to define this is the hooks file (@see LWIP_HOOK_FILENAME) */
#if !defined HTTPD_MAX_WRITE_LEN || defined __DOXYGEN__
#if HTTPD_LIMIT_SENDING_TO_2MSS
#define HTTPD_MAX_WRITE_LEN(pcb) ((u16_t)(2 * altcp_mss(pcb)))
#endif
#endif
/*------------------- FS OPTIONS -------------------*/
/** Set this to 1 and provide the functions:
* - "int fs_open_custom(struct fs_file *file, const char *name)"
* Called first for every opened file to allow opening files
* that are not included in fsdata(_custom).c
* - "void fs_close_custom(struct fs_file *file)"
* Called to free resources allocated by fs_open_custom().
*/
#if !defined LWIP_HTTPD_CUSTOM_FILES || defined __DOXYGEN__
#define LWIP_HTTPD_CUSTOM_FILES 0
#endif
/** Set this to 1 to support fs_read() to dynamically read file data.
* Without this (default=off), only one-block files are supported,
* and the contents must be ready after fs_open().
*/
#if !defined LWIP_HTTPD_DYNAMIC_FILE_READ || defined __DOXYGEN__
#define LWIP_HTTPD_DYNAMIC_FILE_READ 0
#endif
/** Set this to 1 to include an application state argument per file
* that is opened. This allows to keep a state per connection/file.
*/
#if !defined LWIP_HTTPD_FILE_STATE || defined __DOXYGEN__
#define LWIP_HTTPD_FILE_STATE 0
#endif
/** HTTPD_PRECALCULATED_CHECKSUM==1: include precompiled checksums for
* predefined (MSS-sized) chunks of the files to prevent having to calculate
* the checksums at runtime. */
#if !defined HTTPD_PRECALCULATED_CHECKSUM || defined __DOXYGEN__
#define HTTPD_PRECALCULATED_CHECKSUM 0
#endif
/** LWIP_HTTPD_FS_ASYNC_READ==1: support asynchronous read operations
* (fs_read_async returns FS_READ_DELAYED and calls a callback when finished).
*/
#if !defined LWIP_HTTPD_FS_ASYNC_READ || defined __DOXYGEN__
#define LWIP_HTTPD_FS_ASYNC_READ 0
#endif
/** Filename (including path) to use as FS data file */
#if !defined HTTPD_FSDATA_FILE || defined __DOXYGEN__
/* HTTPD_USE_CUSTOM_FSDATA: Compatibility with deprecated lwIP option */
#if defined(HTTPD_USE_CUSTOM_FSDATA) && (HTTPD_USE_CUSTOM_FSDATA != 0)
#define HTTPD_FSDATA_FILE "fsdata.c"
#else
#define HTTPD_FSDATA_FILE "fsdata.c"
#endif
#endif
/**
* @}
*/
#endif /* LWIP_HDR_APPS_HTTPD_OPTS_H */
@@ -0,0 +1,100 @@
/**
* @file
* lwIP iPerf server implementation
*/
/*
* Copyright (c) 2014 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt
*
*/
#ifndef LWIP_HDR_APPS_LWIPERF_H
#define LWIP_HDR_APPS_LWIPERF_H
#include "lwip/opt.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LWIPERF_TCP_PORT_DEFAULT 5001
/** lwIPerf test results */
enum lwiperf_report_type
{
/** The server side test is done */
LWIPERF_TCP_DONE_SERVER,
/** The client side test is done */
LWIPERF_TCP_DONE_CLIENT,
/** Local error lead to test abort */
LWIPERF_TCP_ABORTED_LOCAL,
/** Data check error lead to test abort */
LWIPERF_TCP_ABORTED_LOCAL_DATAERROR,
/** Transmit error lead to test abort */
LWIPERF_TCP_ABORTED_LOCAL_TXERROR,
/** Remote side aborted the test */
LWIPERF_TCP_ABORTED_REMOTE
};
/** Control */
enum lwiperf_client_type
{
/** Unidirectional tx only test */
LWIPERF_CLIENT,
/** Do a bidirectional test simultaneously */
LWIPERF_DUAL,
/** Do a bidirectional test individually */
LWIPERF_TRADEOFF
};
/** Prototype of a report function that is called when a session is finished.
This report function can show the test results.
@param report_type contains the test result */
typedef void (*lwiperf_report_fn)(void *arg, enum lwiperf_report_type report_type,
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec);
void* lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port,
lwiperf_report_fn report_fn, void* report_arg);
void* lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg);
void* lwiperf_start_tcp_client(const ip_addr_t* remote_addr, u16_t remote_port,
enum lwiperf_client_type type,
lwiperf_report_fn report_fn, void* report_arg);
void* lwiperf_start_tcp_client_default(const ip_addr_t* remote_addr,
lwiperf_report_fn report_fn, void* report_arg);
void lwiperf_abort(void* lwiperf_session);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_LWIPERF_H */
@@ -0,0 +1,105 @@
/**
* @file
* MDNS responder
*/
/*
* Copyright (c) 2015 Verisure Innovation AB
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Erik Ekman <erik@kryo.se>
*
*/
#ifndef LWIP_HDR_APPS_MDNS_H
#define LWIP_HDR_APPS_MDNS_H
#include "lwip/apps/mdns_opts.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_MDNS_RESPONDER
enum mdns_sd_proto {
DNSSD_PROTO_UDP = 0,
DNSSD_PROTO_TCP = 1
};
#define MDNS_PROBING_CONFLICT 0
#define MDNS_PROBING_SUCCESSFUL 1
#define MDNS_LABEL_MAXLEN 63
struct mdns_host;
struct mdns_service;
/** Callback function to add text to a reply, called when generating the reply */
typedef void (*service_get_txt_fn_t)(struct mdns_service *service, void *txt_userdata);
/** Callback function to let application know the result of probing network for name
* uniqueness, called with result MDNS_PROBING_SUCCESSFUL if no other node claimed
* use for the name for the netif or a service and is safe to use, or MDNS_PROBING_CONFLICT
* if another node is already using it and mdns is disabled on this interface */
typedef void (*mdns_name_result_cb_t)(struct netif* netif, u8_t result);
void mdns_resp_init(void);
void mdns_resp_register_name_result_cb(mdns_name_result_cb_t cb);
err_t mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl);
err_t mdns_resp_remove_netif(struct netif *netif);
err_t mdns_resp_rename_netif(struct netif *netif, const char *hostname);
s8_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_userdata);
err_t mdns_resp_del_service(struct netif *netif, s8_t slot);
err_t mdns_resp_rename_service(struct netif *netif, s8_t slot, const char *name);
err_t mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len);
void mdns_resp_restart(struct netif *netif);
void mdns_resp_announce(struct netif *netif);
/**
* @ingroup mdns
* Announce IP settings have changed on netif.
* Call this in your callback registered by netif_set_status_callback().
* No need to call this function when LWIP_NETIF_EXT_STATUS_CALLBACK==1,
* this handled automatically for you.
* @param netif The network interface where settings have changed.
*/
#define mdns_resp_netif_settings_changed(netif) mdns_resp_announce(netif)
#endif /* LWIP_MDNS_RESPONDER */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_MDNS_H */
@@ -0,0 +1,81 @@
/**
* @file
* MDNS responder
*/
/*
* Copyright (c) 2015 Verisure Innovation AB
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Erik Ekman <erik@kryo.se>
*
*/
#ifndef LWIP_HDR_APPS_MDNS_OPTS_H
#define LWIP_HDR_APPS_MDNS_OPTS_H
#include "lwip/opt.h"
/**
* @defgroup mdns_opts Options
* @ingroup mdns
* @{
*/
/**
* LWIP_MDNS_RESPONDER==1: Turn on multicast DNS module. UDP must be available for MDNS
* transport. IGMP is needed for IPv4 multicast.
*/
#ifndef LWIP_MDNS_RESPONDER
#define LWIP_MDNS_RESPONDER 0
#endif /* LWIP_MDNS_RESPONDER */
/** The maximum number of services per netif */
#ifndef MDNS_MAX_SERVICES
#define MDNS_MAX_SERVICES 1
#endif
/** MDNS_RESP_USENETIF_EXTCALLBACK==1: register an ext_callback on the netif
* to automatically restart probing/announcing on status or address change.
*/
#ifndef MDNS_RESP_USENETIF_EXTCALLBACK
#define MDNS_RESP_USENETIF_EXTCALLBACK LWIP_NETIF_EXT_STATUS_CALLBACK
#endif
/**
* MDNS_DEBUG: Enable debugging for multicast DNS.
*/
#ifndef MDNS_DEBUG
#define MDNS_DEBUG LWIP_DBG_OFF
#endif
/**
* @}
*/
#endif /* LWIP_HDR_APPS_MDNS_OPTS_H */
@@ -0,0 +1,74 @@
/**
* @file
* MDNS responder private definitions
*/
/*
* Copyright (c) 2015 Verisure Innovation AB
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Erik Ekman <erik@kryo.se>
*
*/
#ifndef LWIP_HDR_MDNS_PRIV_H
#define LWIP_HDR_MDNS_PRIV_H
#include "lwip/apps/mdns_opts.h"
#include "lwip/pbuf.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_MDNS_RESPONDER
/* Domain struct and methods - visible for unit tests */
#define MDNS_DOMAIN_MAXLEN 256
#define MDNS_READNAME_ERROR 0xFFFF
struct mdns_domain {
/* Encoded domain name */
u8_t name[MDNS_DOMAIN_MAXLEN];
/* Total length of domain name, including zero */
u16_t length;
/* Set if compression of this domain is not allowed */
u8_t skip_compression;
};
err_t mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len);
u16_t mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain);
int mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b);
u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain);
#endif /* LWIP_MDNS_RESPONDER */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_MDNS_PRIV_H */
@@ -0,0 +1,205 @@
/**
* @file
* MQTT client
*/
/*
* Copyright (c) 2016 Erik Andersson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Erik Andersson
*
*/
#ifndef LWIP_HDR_APPS_MQTT_CLIENT_H
#define LWIP_HDR_APPS_MQTT_CLIENT_H
#include "lwip/apps/mqtt_opts.h"
#include "lwip/err.h"
#include "lwip/ip_addr.h"
#include "lwip/prot/iana.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct mqtt_client_s mqtt_client_t;
#if LWIP_ALTCP && LWIP_ALTCP_TLS
struct altcp_tls_config;
#endif
/** @ingroup mqtt
* Default MQTT port (non-TLS) */
#define MQTT_PORT LWIP_IANA_PORT_MQTT
/** @ingroup mqtt
* Default MQTT TLS port */
#define MQTT_TLS_PORT LWIP_IANA_PORT_SECURE_MQTT
/*---------------------------------------------------------------------------------------------- */
/* Connection with server */
/**
* @ingroup mqtt
* Client information and connection parameters */
struct mqtt_connect_client_info_t {
/** Client identifier, must be set by caller */
const char *client_id;
/** User name, set to NULL if not used */
const char* client_user;
/** Password, set to NULL if not used */
const char* client_pass;
/** keep alive time in seconds, 0 to disable keep alive functionality*/
u16_t keep_alive;
/** will topic, set to NULL if will is not to be used,
will_msg, will_qos and will retain are then ignored */
const char* will_topic;
/** will_msg, see will_topic */
const char* will_msg;
/** will_qos, see will_topic */
u8_t will_qos;
/** will_retain, see will_topic */
u8_t will_retain;
#if LWIP_ALTCP && LWIP_ALTCP_TLS
/** TLS configuration for secure connections */
struct altcp_tls_config *tls_config;
#endif
};
/**
* @ingroup mqtt
* Connection status codes */
typedef enum
{
/** Accepted */
MQTT_CONNECT_ACCEPTED = 0,
/** Refused protocol version */
MQTT_CONNECT_REFUSED_PROTOCOL_VERSION = 1,
/** Refused identifier */
MQTT_CONNECT_REFUSED_IDENTIFIER = 2,
/** Refused server */
MQTT_CONNECT_REFUSED_SERVER = 3,
/** Refused user credentials */
MQTT_CONNECT_REFUSED_USERNAME_PASS = 4,
/** Refused not authorized */
MQTT_CONNECT_REFUSED_NOT_AUTHORIZED_ = 5,
/** Disconnected */
MQTT_CONNECT_DISCONNECTED = 256,
/** Timeout */
MQTT_CONNECT_TIMEOUT = 257
} mqtt_connection_status_t;
/**
* @ingroup mqtt
* Function prototype for mqtt connection status callback. Called when
* client has connected to the server after initiating a mqtt connection attempt by
* calling mqtt_client_connect() or when connection is closed by server or an error
*
* @param client MQTT client itself
* @param arg Additional argument to pass to the callback function
* @param status Connect result code or disconnection notification @see mqtt_connection_status_t
*
*/
typedef void (*mqtt_connection_cb_t)(mqtt_client_t *client, void *arg, mqtt_connection_status_t status);
/**
* @ingroup mqtt
* Data callback flags */
enum {
/** Flag set when last fragment of data arrives in data callback */
MQTT_DATA_FLAG_LAST = 1
};
/**
* @ingroup mqtt
* Function prototype for MQTT incoming publish data callback function. Called when data
* arrives to a subscribed topic @see mqtt_subscribe
*
* @param arg Additional argument to pass to the callback function
* @param data User data, pointed object, data may not be referenced after callback return,
NULL is passed when all publish data are delivered
* @param len Length of publish data fragment
* @param flags MQTT_DATA_FLAG_LAST set when this call contains the last part of data from publish message
*
*/
typedef void (*mqtt_incoming_data_cb_t)(void *arg, const u8_t *data, u16_t len, u8_t flags);
/**
* @ingroup mqtt
* Function prototype for MQTT incoming publish function. Called when an incoming publish
* arrives to a subscribed topic @see mqtt_subscribe
*
* @param arg Additional argument to pass to the callback function
* @param topic Zero terminated Topic text string, topic may not be referenced after callback return
* @param tot_len Total length of publish data, if set to 0 (no publish payload) data callback will not be invoked
*/
typedef void (*mqtt_incoming_publish_cb_t)(void *arg, const char *topic, u32_t tot_len);
/**
* @ingroup mqtt
* Function prototype for mqtt request callback. Called when a subscribe, unsubscribe
* or publish request has completed
* @param arg Pointer to user data supplied when invoking request
* @param err ERR_OK on success
* ERR_TIMEOUT if no response was received within timeout,
* ERR_ABRT if (un)subscribe was denied
*/
typedef void (*mqtt_request_cb_t)(void *arg, err_t err);
err_t mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ipaddr, u16_t port, mqtt_connection_cb_t cb, void *arg,
const struct mqtt_connect_client_info_t *client_info);
void mqtt_disconnect(mqtt_client_t *client);
mqtt_client_t *mqtt_client_new(void);
void mqtt_client_free(mqtt_client_t* client);
u8_t mqtt_client_is_connected(mqtt_client_t *client);
void mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t,
mqtt_incoming_data_cb_t data_cb, void *arg);
err_t mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub);
/** @ingroup mqtt
*Subscribe to topic */
#define mqtt_subscribe(client, topic, qos, cb, arg) mqtt_sub_unsub(client, topic, qos, cb, arg, 1)
/** @ingroup mqtt
* Unsubscribe to topic */
#define mqtt_unsubscribe(client, topic, cb, arg) mqtt_sub_unsub(client, topic, 0, cb, arg, 0)
err_t mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain,
mqtt_request_cb_t cb, void *arg);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_MQTT_CLIENT_H */
@@ -0,0 +1,103 @@
/**
* @file
* MQTT client options
*/
/*
* Copyright (c) 2016 Erik Andersson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Erik Andersson
*
*/
#ifndef LWIP_HDR_APPS_MQTT_OPTS_H
#define LWIP_HDR_APPS_MQTT_OPTS_H
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup mqtt_opts Options
* @ingroup mqtt
* @{
*/
/**
* Output ring-buffer size, must be able to fit largest outgoing publish message topic+payloads
*/
#ifndef MQTT_OUTPUT_RINGBUF_SIZE
#define MQTT_OUTPUT_RINGBUF_SIZE 256
#endif
/**
* Number of bytes in receive buffer, must be at least the size of the longest incoming topic + 8
* If one wants to avoid fragmented incoming publish, set length to max incoming topic length + max payload length + 8
*/
#ifndef MQTT_VAR_HEADER_BUFFER_LEN
#define MQTT_VAR_HEADER_BUFFER_LEN 128
#endif
/**
* Maximum number of pending subscribe, unsubscribe and publish requests to server .
*/
#ifndef MQTT_REQ_MAX_IN_FLIGHT
#define MQTT_REQ_MAX_IN_FLIGHT 4
#endif
/**
* Seconds between each cyclic timer call.
*/
#ifndef MQTT_CYCLIC_TIMER_INTERVAL
#define MQTT_CYCLIC_TIMER_INTERVAL 5
#endif
/**
* Publish, subscribe and unsubscribe request timeout in seconds.
*/
#ifndef MQTT_REQ_TIMEOUT
#define MQTT_REQ_TIMEOUT 30
#endif
/**
* Seconds for MQTT connect response timeout after sending connect request
*/
#ifndef MQTT_CONNECT_TIMOUT
#define MQTT_CONNECT_TIMOUT 100
#endif
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_MQTT_OPTS_H */
@@ -0,0 +1,104 @@
/**
* @file
* MQTT client (private interface)
*/
/*
* Copyright (c) 2016 Erik Andersson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Erik Andersson
*
*/
#ifndef LWIP_HDR_APPS_MQTT_PRIV_H
#define LWIP_HDR_APPS_MQTT_PRIV_H
#include "lwip/apps/mqtt.h"
#include "lwip/altcp.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Pending request item, binds application callback to pending server requests */
struct mqtt_request_t
{
/** Next item in list, NULL means this is the last in chain,
next pointing at itself means request is unallocated */
struct mqtt_request_t *next;
/** Callback to upper layer */
mqtt_request_cb_t cb;
void *arg;
/** MQTT packet identifier */
u16_t pkt_id;
/** Expire time relative to element before this */
u16_t timeout_diff;
};
/** Ring buffer */
struct mqtt_ringbuf_t {
u16_t put;
u16_t get;
u8_t buf[MQTT_OUTPUT_RINGBUF_SIZE];
};
/** MQTT client */
struct mqtt_client_s
{
/** Timers and timeouts */
u16_t cyclic_tick;
u16_t keep_alive;
u16_t server_watchdog;
/** Packet identifier generator*/
u16_t pkt_id_seq;
/** Packet identifier of pending incoming publish */
u16_t inpub_pkt_id;
/** Connection state */
u8_t conn_state;
struct altcp_pcb *conn;
/** Connection callback */
void *connect_arg;
mqtt_connection_cb_t connect_cb;
/** Pending requests to server */
struct mqtt_request_t *pend_req_queue;
struct mqtt_request_t req_list[MQTT_REQ_MAX_IN_FLIGHT];
void *inpub_arg;
/** Incoming data callback */
mqtt_incoming_data_cb_t data_cb;
mqtt_incoming_publish_cb_t pub_cb;
/** Input */
u32_t msg_idx;
u8_t rx_buffer[MQTT_VAR_HEADER_BUFFER_LEN];
/** Output ring-buffer */
struct mqtt_ringbuf_t output;
};
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_MQTT_PRIV_H */
@@ -0,0 +1,51 @@
/**
* @file
* NETBIOS name service responder
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#ifndef LWIP_HDR_APPS_NETBIOS_H
#define LWIP_HDR_APPS_NETBIOS_H
#include "lwip/apps/netbiosns_opts.h"
#ifdef __cplusplus
extern "C" {
#endif
void netbiosns_init(void);
#ifndef NETBIOS_LWIP_NAME
void netbiosns_set_name(const char* hostname);
#endif
void netbiosns_stop(void);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_NETBIOS_H */
@@ -0,0 +1,66 @@
/**
* @file
* NETBIOS name service responder options
*/
/*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#ifndef LWIP_HDR_APPS_NETBIOS_OPTS_H
#define LWIP_HDR_APPS_NETBIOS_OPTS_H
#include "lwip/opt.h"
/**
* @defgroup netbiosns_opts Options
* @ingroup netbiosns
* @{
*/
/** NetBIOS name of lwip device
* This must be uppercase until NETBIOS_STRCMP() is defined to a string
* comparision function that is case insensitive.
* If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME):
* (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "")
*
* If this is not defined, netbiosns_set_name() can be called at runtime to change the name.
*/
#ifdef __DOXYGEN__
#define NETBIOS_LWIP_NAME "NETBIOSLWIPDEV"
#endif
/** Respond to NetBIOS name queries
* Default is disabled
*/
#if !defined LWIP_NETBIOS_RESPOND_NAME_QUERY || defined __DOXYGEN__
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 0
#endif
/**
* @}
*/
#endif /* LWIP_HDR_APPS_NETBIOS_OPTS_H */
@@ -0,0 +1,128 @@
#ifndef LWIP_HDR_APPS_SMTP_H
#define LWIP_HDR_APPS_SMTP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "lwip/apps/smtp_opts.h"
#include "lwip/err.h"
#include "lwip/prot/iana.h"
/** The default TCP port used for SMTP */
#define SMTP_DEFAULT_PORT LWIP_IANA_PORT_SMTP
/** The default TCP port used for SMTPS */
#define SMTPS_DEFAULT_PORT LWIP_IANA_PORT_SMTPS
/** Email successfully sent */
#define SMTP_RESULT_OK 0
/** Unknown error */
#define SMTP_RESULT_ERR_UNKNOWN 1
/** Connection to server failed */
#define SMTP_RESULT_ERR_CONNECT 2
/** Failed to resolve server hostname */
#define SMTP_RESULT_ERR_HOSTNAME 3
/** Connection unexpectedly closed by remote server */
#define SMTP_RESULT_ERR_CLOSED 4
/** Connection timed out (server didn't respond in time) */
#define SMTP_RESULT_ERR_TIMEOUT 5
/** Server responded with an unknown response code */
#define SMTP_RESULT_ERR_SVR_RESP 6
/** Out of resources locally */
#define SMTP_RESULT_ERR_MEM 7
/** Prototype of an smtp callback function
*
* @param arg argument specified when initiating the email
* @param smtp_result result of the mail transfer (see defines SMTP_RESULT_*)
* @param srv_err if aborted by the server, this contains the error code received
* @param err an error returned by internal lwip functions, can help to specify
* the source of the error but must not necessarily be != ERR_OK
*/
typedef void (*smtp_result_fn)(void *arg, u8_t smtp_result, u16_t srv_err, err_t err);
/** This structure is used as argument for smtp_send_mail_int(),
* which in turn can be used with tcpip_callback() to send mail
* from interrupt context, e.g. like this:
* struct smtp_send_request *req; (to be filled)
* tcpip_try_callback(smtp_send_mail_int, (void*)req);
*
* For member description, see parameter description of smtp_send_mail().
* When using with tcpip_callback, this structure has to stay allocated
* (e.g. using mem_malloc/mem_free) until its 'callback_fn' is called.
*/
struct smtp_send_request {
const char *from;
const char* to;
const char* subject;
const char* body;
smtp_result_fn callback_fn;
void* callback_arg;
/** If this is != 0, data is *not* copied into an extra buffer
* but used from the pointers supplied in this struct.
* This means less memory usage, but data must stay untouched until
* the callback function is called. */
u8_t static_data;
};
#if SMTP_BODYDH
#ifndef SMTP_BODYDH_BUFFER_SIZE
#define SMTP_BODYDH_BUFFER_SIZE 256
#endif /* SMTP_BODYDH_BUFFER_SIZE */
struct smtp_bodydh {
u16_t state;
u16_t length; /* Length of content in buffer */
char buffer[SMTP_BODYDH_BUFFER_SIZE]; /* buffer for generated content */
#ifdef SMTP_BODYDH_USER_SIZE
u8_t user[SMTP_BODYDH_USER_SIZE];
#endif /* SMTP_BODYDH_USER_SIZE */
};
enum bdh_retvals_e {
BDH_DONE = 0,
BDH_WORKING
};
/** Prototype of an smtp body callback function
* It receives a struct smtp_bodydh, and a buffer to write data,
* must return BDH_WORKING to be called again and BDH_DONE when
* it has finished processing. This one tries to fill one TCP buffer with
* data, your function will be repeatedly called until that happens; so if you
* know you'll be taking too long to serve your request, pause once in a while
* by writing length=0 to avoid hogging system resources
*
* @param arg argument specified when initiating the email
* @param smtp_bodydh state handling + buffer structure
*/
typedef int (*smtp_bodycback_fn)(void *arg, struct smtp_bodydh *bodydh);
err_t smtp_send_mail_bodycback(const char *from, const char* to, const char* subject,
smtp_bodycback_fn bodycback_fn, smtp_result_fn callback_fn, void* callback_arg);
#endif /* SMTP_BODYDH */
err_t smtp_set_server_addr(const char* server);
void smtp_set_server_port(u16_t port);
#if LWIP_ALTCP && LWIP_ALTCP_TLS
struct altcp_tls_config;
void smtp_set_tls_config(struct altcp_tls_config *tls_config);
#endif
err_t smtp_set_auth(const char* username, const char* pass);
err_t smtp_send_mail(const char *from, const char* to, const char* subject, const char* body,
smtp_result_fn callback_fn, void* callback_arg);
err_t smtp_send_mail_static(const char *from, const char* to, const char* subject, const char* body,
smtp_result_fn callback_fn, void* callback_arg);
void smtp_send_mail_int(void *arg);
#ifdef LWIP_DEBUG
const char* smtp_result_str(u8_t smtp_result);
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SMTP_H */
@@ -0,0 +1,81 @@
#ifndef LWIP_HDR_APPS_SMTP_OPTS_H
#define LWIP_HDR_APPS_SMTP_OPTS_H
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup smtp_opts Options
* @ingroup smtp
*
* @{
*/
/** Set this to 1 to enable data handler callback on BODY */
#ifndef SMTP_BODYDH
#define SMTP_BODYDH 0
#endif
/** SMTP_DEBUG: Enable debugging for SNTP. */
#ifndef SMTP_DEBUG
#define SMTP_DEBUG LWIP_DBG_OFF
#endif
/** Maximum length reserved for server name including terminating 0 byte */
#ifndef SMTP_MAX_SERVERNAME_LEN
#define SMTP_MAX_SERVERNAME_LEN 256
#endif
/** Maximum length reserved for username */
#ifndef SMTP_MAX_USERNAME_LEN
#define SMTP_MAX_USERNAME_LEN 32
#endif
/** Maximum length reserved for password */
#ifndef SMTP_MAX_PASS_LEN
#define SMTP_MAX_PASS_LEN 32
#endif
/** Set this to 0 if you know the authentication data will not change
* during the smtp session, which saves some heap space. */
#ifndef SMTP_COPY_AUTHDATA
#define SMTP_COPY_AUTHDATA 1
#endif
/** Set this to 0 to save some code space if you know for sure that all data
* passed to this module conforms to the requirements in the SMTP RFC.
* WARNING: use this with care!
*/
#ifndef SMTP_CHECK_DATA
#define SMTP_CHECK_DATA 1
#endif
/** Set this to 1 to enable AUTH PLAIN support */
#ifndef SMTP_SUPPORT_AUTH_PLAIN
#define SMTP_SUPPORT_AUTH_PLAIN 1
#endif
/** Set this to 1 to enable AUTH LOGIN support */
#ifndef SMTP_SUPPORT_AUTH_LOGIN
#define SMTP_SUPPORT_AUTH_LOGIN 1
#endif
/* Memory allocation/deallocation can be overridden... */
#ifndef SMTP_STATE_MALLOC
#define SMTP_STATE_MALLOC(size) mem_malloc(size)
#define SMTP_STATE_FREE(ptr) mem_free(ptr)
#endif
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* SMTP_OPTS_H */
@@ -0,0 +1,135 @@
/**
* @file
* SNMP server main API - start and basic configuration
*/
/*
* Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv>
* Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Leon Woestenberg <leon.woestenberg@axon.tv>
* Martin Hentschel <info@cl-soft.de>
*
*/
#ifndef LWIP_HDR_APPS_SNMP_H
#define LWIP_HDR_APPS_SNMP_H
#include "lwip/apps/snmp_opts.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/err.h"
#include "lwip/apps/snmp_core.h"
/** SNMP variable binding descriptor (publically needed for traps) */
struct snmp_varbind
{
/** pointer to next varbind, NULL for last in list */
struct snmp_varbind *next;
/** pointer to previous varbind, NULL for first in list */
struct snmp_varbind *prev;
/** object identifier */
struct snmp_obj_id oid;
/** value ASN1 type */
u8_t type;
/** object value length */
u16_t value_len;
/** object value */
void *value;
};
/**
* @ingroup snmp_core
* Agent setup, start listening to port 161.
*/
void snmp_init(void);
void snmp_set_mibs(const struct snmp_mib **mibs, u8_t num_mibs);
void snmp_set_device_enterprise_oid(const struct snmp_obj_id* device_enterprise_oid);
const struct snmp_obj_id* snmp_get_device_enterprise_oid(void);
void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable);
void snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst);
/** Generic trap: cold start */
#define SNMP_GENTRAP_COLDSTART 0
/** Generic trap: warm start */
#define SNMP_GENTRAP_WARMSTART 1
/** Generic trap: link down */
#define SNMP_GENTRAP_LINKDOWN 2
/** Generic trap: link up */
#define SNMP_GENTRAP_LINKUP 3
/** Generic trap: authentication failure */
#define SNMP_GENTRAP_AUTH_FAILURE 4
/** Generic trap: EGP neighbor lost */
#define SNMP_GENTRAP_EGP_NEIGHBOR_LOSS 5
/** Generic trap: enterprise specific */
#define SNMP_GENTRAP_ENTERPRISE_SPECIFIC 6
err_t snmp_send_trap_generic(s32_t generic_trap);
err_t snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds);
err_t snmp_send_trap(const struct snmp_obj_id* oid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds);
#define SNMP_AUTH_TRAPS_DISABLED 0
#define SNMP_AUTH_TRAPS_ENABLED 1
void snmp_set_auth_traps_enabled(u8_t enable);
u8_t snmp_get_auth_traps_enabled(void);
u8_t snmp_v1_enabled(void);
u8_t snmp_v2c_enabled(void);
u8_t snmp_v3_enabled(void);
void snmp_v1_enable(u8_t enable);
void snmp_v2c_enable(u8_t enable);
void snmp_v3_enable(u8_t enable);
const char * snmp_get_community(void);
const char * snmp_get_community_write(void);
const char * snmp_get_community_trap(void);
void snmp_set_community(const char * const community);
void snmp_set_community_write(const char * const community);
void snmp_set_community_trap(const char * const community);
void snmp_coldstart_trap(void);
void snmp_authfail_trap(void);
typedef void (*snmp_write_callback_fct)(const u32_t* oid, u8_t oid_len, void* callback_arg);
void snmp_set_write_callback(snmp_write_callback_fct write_callback, void* callback_arg);
#endif /* LWIP_SNMP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNMP_H */
@@ -0,0 +1,377 @@
/**
* @file
* SNMP core API for implementing MIBs
*/
/*
* Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* Author: Christiaan Simons <christiaan.simons@axon.tv>
* Martin Hentschel <info@cl-soft.de>
*/
#ifndef LWIP_HDR_APPS_SNMP_CORE_H
#define LWIP_HDR_APPS_SNMP_CORE_H
#include "lwip/apps/snmp_opts.h"
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
/* basic ASN1 defines */
#define SNMP_ASN1_CLASS_UNIVERSAL 0x00
#define SNMP_ASN1_CLASS_APPLICATION 0x40
#define SNMP_ASN1_CLASS_CONTEXT 0x80
#define SNMP_ASN1_CLASS_PRIVATE 0xC0
#define SNMP_ASN1_CONTENTTYPE_PRIMITIVE 0x00
#define SNMP_ASN1_CONTENTTYPE_CONSTRUCTED 0x20
/* universal tags (from ASN.1 spec.) */
#define SNMP_ASN1_UNIVERSAL_END_OF_CONTENT 0
#define SNMP_ASN1_UNIVERSAL_INTEGER 2
#define SNMP_ASN1_UNIVERSAL_OCTET_STRING 4
#define SNMP_ASN1_UNIVERSAL_NULL 5
#define SNMP_ASN1_UNIVERSAL_OBJECT_ID 6
#define SNMP_ASN1_UNIVERSAL_SEQUENCE_OF 16
/* application specific (SNMP) tags (from SNMPv2-SMI) */
#define SNMP_ASN1_APPLICATION_IPADDR 0 /* [APPLICATION 0] IMPLICIT OCTET STRING (SIZE (4)) */
#define SNMP_ASN1_APPLICATION_COUNTER 1 /* [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) => u32_t */
#define SNMP_ASN1_APPLICATION_GAUGE 2 /* [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) => u32_t */
#define SNMP_ASN1_APPLICATION_TIMETICKS 3 /* [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) => u32_t */
#define SNMP_ASN1_APPLICATION_OPAQUE 4 /* [APPLICATION 4] IMPLICIT OCTET STRING */
#define SNMP_ASN1_APPLICATION_COUNTER64 6 /* [APPLICATION 6] IMPLICIT INTEGER (0..18446744073709551615) */
/* context specific (SNMP) tags (from RFC 1905) */
#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE 1
/* full ASN1 type defines */
#define SNMP_ASN1_TYPE_END_OF_CONTENT (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_END_OF_CONTENT)
#define SNMP_ASN1_TYPE_INTEGER (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_INTEGER)
#define SNMP_ASN1_TYPE_OCTET_STRING (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OCTET_STRING)
#define SNMP_ASN1_TYPE_NULL (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_NULL)
#define SNMP_ASN1_TYPE_OBJECT_ID (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OBJECT_ID)
#define SNMP_ASN1_TYPE_SEQUENCE (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_UNIVERSAL_SEQUENCE_OF)
#define SNMP_ASN1_TYPE_IPADDR (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_IPADDR)
#define SNMP_ASN1_TYPE_IPADDRESS SNMP_ASN1_TYPE_IPADDR
#define SNMP_ASN1_TYPE_COUNTER (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER)
#define SNMP_ASN1_TYPE_COUNTER32 SNMP_ASN1_TYPE_COUNTER
#define SNMP_ASN1_TYPE_GAUGE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_GAUGE)
#define SNMP_ASN1_TYPE_GAUGE32 SNMP_ASN1_TYPE_GAUGE
#define SNMP_ASN1_TYPE_UNSIGNED32 SNMP_ASN1_TYPE_GAUGE
#define SNMP_ASN1_TYPE_TIMETICKS (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_TIMETICKS)
#define SNMP_ASN1_TYPE_OPAQUE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_OPAQUE)
#if LWIP_HAVE_INT64
#define SNMP_ASN1_TYPE_COUNTER64 (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER64)
#endif
#define SNMP_VARBIND_EXCEPTION_OFFSET 0xF0
#define SNMP_VARBIND_EXCEPTION_MASK 0x0F
/** error codes predefined by SNMP prot. */
typedef enum {
SNMP_ERR_NOERROR = 0,
/*
outdated v1 error codes. do not use anmore!
#define SNMP_ERR_NOSUCHNAME 2 use SNMP_ERR_NOSUCHINSTANCE instead
#define SNMP_ERR_BADVALUE 3 use SNMP_ERR_WRONGTYPE,SNMP_ERR_WRONGLENGTH,SNMP_ERR_WRONGENCODING or SNMP_ERR_WRONGVALUE instead
#define SNMP_ERR_READONLY 4 use SNMP_ERR_NOTWRITABLE instead
*/
SNMP_ERR_GENERROR = 5,
SNMP_ERR_NOACCESS = 6,
SNMP_ERR_WRONGTYPE = 7,
SNMP_ERR_WRONGLENGTH = 8,
SNMP_ERR_WRONGENCODING = 9,
SNMP_ERR_WRONGVALUE = 10,
SNMP_ERR_NOCREATION = 11,
SNMP_ERR_INCONSISTENTVALUE = 12,
SNMP_ERR_RESOURCEUNAVAILABLE = 13,
SNMP_ERR_COMMITFAILED = 14,
SNMP_ERR_UNDOFAILED = 15,
SNMP_ERR_NOTWRITABLE = 17,
SNMP_ERR_INCONSISTENTNAME = 18,
SNMP_ERR_NOSUCHINSTANCE = SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE
} snmp_err_t;
/** internal object identifier representation */
struct snmp_obj_id
{
u8_t len;
u32_t id[SNMP_MAX_OBJ_ID_LEN];
};
struct snmp_obj_id_const_ref
{
u8_t len;
const u32_t* id;
};
extern const struct snmp_obj_id_const_ref snmp_zero_dot_zero; /* administrative identifier from SNMPv2-SMI */
/** SNMP variant value, used as reference in struct snmp_node_instance and table implementation */
union snmp_variant_value
{
void* ptr;
const void* const_ptr;
u32_t u32;
s32_t s32;
#if LWIP_HAVE_INT64
u64_t u64;
#endif
};
/**
SNMP MIB node types
tree node is the only node the stack can process in order to walk the tree,
all other nodes are assumed to be leaf nodes.
This cannot be an enum because users may want to define their own node types.
*/
#define SNMP_NODE_TREE 0x00
/* predefined leaf node types */
#define SNMP_NODE_SCALAR 0x01
#define SNMP_NODE_SCALAR_ARRAY 0x02
#define SNMP_NODE_TABLE 0x03
#define SNMP_NODE_THREADSYNC 0x04
/** node "base class" layout, the mandatory fields for a node */
struct snmp_node
{
/** one out of SNMP_NODE_TREE or any leaf node type (like SNMP_NODE_SCALAR) */
u8_t node_type;
/** the number assigned to this node which used as part of the full OID */
u32_t oid;
};
/** SNMP node instance access types */
typedef enum {
SNMP_NODE_INSTANCE_ACCESS_READ = 1,
SNMP_NODE_INSTANCE_ACCESS_WRITE = 2,
SNMP_NODE_INSTANCE_READ_ONLY = SNMP_NODE_INSTANCE_ACCESS_READ,
SNMP_NODE_INSTANCE_READ_WRITE = (SNMP_NODE_INSTANCE_ACCESS_READ | SNMP_NODE_INSTANCE_ACCESS_WRITE),
SNMP_NODE_INSTANCE_WRITE_ONLY = SNMP_NODE_INSTANCE_ACCESS_WRITE,
SNMP_NODE_INSTANCE_NOT_ACCESSIBLE = 0
} snmp_access_t;
struct snmp_node_instance;
typedef s16_t (*node_instance_get_value_method)(struct snmp_node_instance*, void*);
typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*, u16_t, void*);
typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*);
typedef void (*node_instance_release_method)(struct snmp_node_instance*);
#define SNMP_GET_VALUE_RAW_DATA 0x4000 /* do not use 0x8000 because return value of node_instance_get_value_method is signed16 and 0x8000 would be the signed bit */
/** SNMP node instance */
struct snmp_node_instance
{
/** prefilled with the node, get_instance() is called on; may be changed by user to any value to pass an arbitrary node between calls to get_instance() and get_value/test_value/set_value */
const struct snmp_node* node;
/** prefilled with the instance id requested; for get_instance() this is the exact oid requested; for get_next_instance() this is the relative starting point, stack expects relative oid of next node here */
struct snmp_obj_id instance_oid;
/** ASN type for this object (see snmp_asn1.h for definitions) */
u8_t asn1_type;
/** one out of instance access types defined above (SNMP_NODE_INSTANCE_READ_ONLY,...) */
snmp_access_t access;
/** returns object value for the given object identifier. Return values <0 to indicate an error */
node_instance_get_value_method get_value;
/** tests length and/or range BEFORE setting */
node_instance_set_test_method set_test;
/** sets object value, only called when set_test() was successful */
node_instance_set_value_method set_value;
/** called in any case when the instance is not required anymore by stack (useful for freeing memory allocated in get_instance/get_next_instance methods) */
node_instance_release_method release_instance;
/** reference to pass arbitrary value between calls to get_instance() and get_value/test_value/set_value */
union snmp_variant_value reference;
/** see reference (if reference is a pointer, the length of underlying data may be stored here or anything else) */
u32_t reference_len;
};
/** SNMP tree node */
struct snmp_tree_node
{
/** inherited "base class" members */
struct snmp_node node;
u16_t subnode_count;
const struct snmp_node* const *subnodes;
};
#define SNMP_CREATE_TREE_NODE(oid, subnodes) \
{{ SNMP_NODE_TREE, (oid) }, \
(u16_t)LWIP_ARRAYSIZE(subnodes), (subnodes) }
#define SNMP_CREATE_EMPTY_TREE_NODE(oid) \
{{ SNMP_NODE_TREE, (oid) }, \
0, NULL }
/** SNMP leaf node */
struct snmp_leaf_node
{
/** inherited "base class" members */
struct snmp_node node;
snmp_err_t (*get_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
snmp_err_t (*get_next_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
};
/** represents a single mib with its base oid and root node */
struct snmp_mib
{
const u32_t *base_oid;
u8_t base_oid_len;
const struct snmp_node *root_node;
};
#define SNMP_MIB_CREATE(oid_list, root_node) { (oid_list), (u8_t)LWIP_ARRAYSIZE(oid_list), root_node }
/** OID range structure */
struct snmp_oid_range
{
u32_t min;
u32_t max;
};
/** checks if incoming OID length and values are in allowed ranges */
u8_t snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len);
typedef enum {
SNMP_NEXT_OID_STATUS_SUCCESS,
SNMP_NEXT_OID_STATUS_NO_MATCH,
SNMP_NEXT_OID_STATUS_BUF_TO_SMALL
} snmp_next_oid_status_t;
/** state for next_oid_init / next_oid_check functions */
struct snmp_next_oid_state
{
const u32_t* start_oid;
u8_t start_oid_len;
u32_t* next_oid;
u8_t next_oid_len;
u8_t next_oid_max_len;
snmp_next_oid_status_t status;
void* reference;
};
void snmp_next_oid_init(struct snmp_next_oid_state *state,
const u32_t *start_oid, u8_t start_oid_len,
u32_t *next_oid_buf, u8_t next_oid_max_len);
u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len);
u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, u8_t oid_len, void* reference);
void snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
void snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
void snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
void snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len);
u8_t snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
s8_t snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len);
#if LWIP_IPV4
u8_t snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip);
void snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid);
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
u8_t snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip);
void snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid);
#endif /* LWIP_IPV6 */
#if LWIP_IPV4 || LWIP_IPV6
u8_t snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid);
u8_t snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid);
u8_t snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip);
u8_t snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port);
#endif /* LWIP_IPV4 || LWIP_IPV6 */
struct netif;
u8_t netif_to_num(const struct netif *netif);
snmp_err_t snmp_set_test_ok(struct snmp_node_instance* instance, u16_t value_len, void* value); /* generic function which can be used if test is always successful */
err_t snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value);
err_t snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value);
u8_t snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count);
u8_t snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value);
struct snmp_statistics
{
u32_t inpkts;
u32_t outpkts;
u32_t inbadversions;
u32_t inbadcommunitynames;
u32_t inbadcommunityuses;
u32_t inasnparseerrs;
u32_t intoobigs;
u32_t innosuchnames;
u32_t inbadvalues;
u32_t inreadonlys;
u32_t ingenerrs;
u32_t intotalreqvars;
u32_t intotalsetvars;
u32_t ingetrequests;
u32_t ingetnexts;
u32_t insetrequests;
u32_t ingetresponses;
u32_t intraps;
u32_t outtoobigs;
u32_t outnosuchnames;
u32_t outbadvalues;
u32_t outgenerrs;
u32_t outgetrequests;
u32_t outgetnexts;
u32_t outsetrequests;
u32_t outgetresponses;
u32_t outtraps;
#if LWIP_SNMP_V3
u32_t unsupportedseclevels;
u32_t notintimewindows;
u32_t unknownusernames;
u32_t unknownengineids;
u32_t wrongdigests;
u32_t decryptionerrors;
#endif
};
extern struct snmp_statistics snmp_stats;
#ifdef __cplusplus
}
#endif
#endif /* LWIP_SNMP */
#endif /* LWIP_HDR_APPS_SNMP_CORE_H */
@@ -0,0 +1,78 @@
/**
* @file
* SNMP MIB2 API
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
*
*/
#ifndef LWIP_HDR_APPS_SNMP_MIB2_H
#define LWIP_HDR_APPS_SNMP_MIB2_H
#include "lwip/apps/snmp_opts.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
#if SNMP_LWIP_MIB2
#include "lwip/apps/snmp_core.h"
extern const struct snmp_mib mib2;
#if SNMP_USE_NETCONN
#include "lwip/apps/snmp_threadsync.h"
void snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg);
extern struct snmp_threadsync_instance snmp_mib2_lwip_locks;
#endif
#ifndef SNMP_SYSSERVICES
#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2))
#endif
void snmp_mib2_set_sysdescr(const u8_t* str, const u16_t* len); /* read-only be defintion */
void snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
void snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
void snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
void snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
void snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize);
void snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen);
#endif /* SNMP_LWIP_MIB2 */
#endif /* LWIP_SNMP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNMP_MIB2_H */
@@ -0,0 +1,297 @@
/**
* @file
* SNMP server options list
*/
/*
* Copyright (c) 2015 Dirk Ziegelmeier
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Dirk Ziegelmeier
*
*/
#ifndef LWIP_HDR_SNMP_OPTS_H
#define LWIP_HDR_SNMP_OPTS_H
#include "lwip/opt.h"
/**
* @defgroup snmp_opts Options
* @ingroup snmp
* @{
*/
/**
* LWIP_SNMP==1: This enables the lwIP SNMP agent. UDP must be available
* for SNMP transport.
* If you want to use your own SNMP agent, leave this disabled.
* To integrate MIB2 of an external agent, you need to enable
* LWIP_MIB2_CALLBACKS and MIB2_STATS. This will give you the callbacks
* and statistics counters you need to get MIB2 working.
*/
#if !defined LWIP_SNMP || defined __DOXYGEN__
#define LWIP_SNMP 0
#endif
/**
* SNMP_USE_NETCONN: Use netconn API instead of raw API.
* Makes SNMP agent run in a worker thread, so blocking operations
* can be done in MIB calls.
*/
#if !defined SNMP_USE_NETCONN || defined __DOXYGEN__
#define SNMP_USE_NETCONN 0
#endif
/**
* SNMP_USE_RAW: Use raw API.
* SNMP agent does not run in a worker thread, so blocking operations
* should not be done in MIB calls.
*/
#if !defined SNMP_USE_RAW || defined __DOXYGEN__
#define SNMP_USE_RAW 1
#endif
#if SNMP_USE_NETCONN && SNMP_USE_RAW
#error SNMP stack can use only one of the APIs {raw, netconn}
#endif
#if LWIP_SNMP && !SNMP_USE_NETCONN && !SNMP_USE_RAW
#error SNMP stack needs a receive API and UDP {raw, netconn}
#endif
#if SNMP_USE_NETCONN
/**
* SNMP_STACK_SIZE: Stack size of SNMP netconn worker thread
*/
#if !defined SNMP_STACK_SIZE || defined __DOXYGEN__
#define SNMP_STACK_SIZE DEFAULT_THREAD_STACKSIZE
#endif
/**
* SNMP_THREAD_PRIO: SNMP netconn worker thread priority
*/
#if !defined SNMP_THREAD_PRIO || defined __DOXYGEN__
#define SNMP_THREAD_PRIO DEFAULT_THREAD_PRIO
#endif
#endif /* SNMP_USE_NETCONN */
/**
* SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap
* destination is required
*/
#if !defined SNMP_TRAP_DESTINATIONS || defined __DOXYGEN__
#define SNMP_TRAP_DESTINATIONS 1
#endif
/**
* Only allow SNMP write actions that are 'safe' (e.g. disabling netifs is not
* a safe action and disabled when SNMP_SAFE_REQUESTS = 1).
* Unsafe requests are disabled by default!
*/
#if !defined SNMP_SAFE_REQUESTS || defined __DOXYGEN__
#define SNMP_SAFE_REQUESTS 1
#endif
/**
* The maximum length of strings used.
*/
#if !defined SNMP_MAX_OCTET_STRING_LEN || defined __DOXYGEN__
#define SNMP_MAX_OCTET_STRING_LEN 127
#endif
/**
* The maximum number of Sub ID's inside an object identifier.
* Indirectly this also limits the maximum depth of SNMP tree.
*/
#if !defined SNMP_MAX_OBJ_ID_LEN || defined __DOXYGEN__
#define SNMP_MAX_OBJ_ID_LEN 50
#endif
#if !defined SNMP_MAX_VALUE_SIZE || defined __DOXYGEN__
/**
* The minimum size of a value.
*/
#define SNMP_MIN_VALUE_SIZE (2 * sizeof(u32_t*)) /* size required to store the basic types (8 bytes for counter64) */
/**
* The maximum size of a value.
*/
#define SNMP_MAX_VALUE_SIZE LWIP_MAX(LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN), sizeof(u32_t)*(SNMP_MAX_OBJ_ID_LEN)), SNMP_MIN_VALUE_SIZE)
#endif
/**
* The snmp read-access community. Used for write-access and traps, too
* unless SNMP_COMMUNITY_WRITE or SNMP_COMMUNITY_TRAP are enabled, respectively.
*/
#if !defined SNMP_COMMUNITY || defined __DOXYGEN__
#define SNMP_COMMUNITY "public"
#endif
/**
* The snmp write-access community.
* Set this community to "" in order to disallow any write access.
*/
#if !defined SNMP_COMMUNITY_WRITE || defined __DOXYGEN__
#define SNMP_COMMUNITY_WRITE "private"
#endif
/**
* The snmp community used for sending traps.
*/
#if !defined SNMP_COMMUNITY_TRAP || defined __DOXYGEN__
#define SNMP_COMMUNITY_TRAP "public"
#endif
/**
* The maximum length of community string.
* If community names shall be adjusted at runtime via snmp_set_community() calls,
* enter here the possible maximum length (+1 for terminating null character).
*/
#if !defined SNMP_MAX_COMMUNITY_STR_LEN || defined __DOXYGEN__
#define SNMP_MAX_COMMUNITY_STR_LEN LWIP_MAX(LWIP_MAX(sizeof(SNMP_COMMUNITY), sizeof(SNMP_COMMUNITY_WRITE)), sizeof(SNMP_COMMUNITY_TRAP))
#endif
/**
* The OID identifiying the device. This may be the enterprise OID itself or any OID located below it in tree.
*/
#if !defined SNMP_DEVICE_ENTERPRISE_OID || defined __DOXYGEN__
#define SNMP_LWIP_ENTERPRISE_OID 26381
/**
* IANA assigned enterprise ID for lwIP is 26381
* @see http://www.iana.org/assignments/enterprise-numbers
*
* @note this enterprise ID is assigned to the lwIP project,
* all object identifiers living under this ID are assigned
* by the lwIP maintainers!
* @note don't change this define, use snmp_set_device_enterprise_oid()
*
* If you need to create your own private MIB you'll need
* to apply for your own enterprise ID with IANA:
* http://www.iana.org/numbers.html
*/
#define SNMP_DEVICE_ENTERPRISE_OID {1, 3, 6, 1, 4, 1, SNMP_LWIP_ENTERPRISE_OID}
/**
* Length of SNMP_DEVICE_ENTERPRISE_OID
*/
#define SNMP_DEVICE_ENTERPRISE_OID_LEN 7
#endif
/**
* SNMP_DEBUG: Enable debugging for SNMP messages.
*/
#if !defined SNMP_DEBUG || defined __DOXYGEN__
#define SNMP_DEBUG LWIP_DBG_OFF
#endif
/**
* SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs.
*/
#if !defined SNMP_MIB_DEBUG || defined __DOXYGEN__
#define SNMP_MIB_DEBUG LWIP_DBG_OFF
#endif
/**
* Indicates if the MIB2 implementation of LWIP SNMP stack is used.
*/
#if !defined SNMP_LWIP_MIB2 || defined __DOXYGEN__
#define SNMP_LWIP_MIB2 LWIP_SNMP
#endif
/**
* Value return for sysDesc field of MIB2.
*/
#if !defined SNMP_LWIP_MIB2_SYSDESC || defined __DOXYGEN__
#define SNMP_LWIP_MIB2_SYSDESC "lwIP"
#endif
/**
* Value return for sysName field of MIB2.
* To make sysName field settable, call snmp_mib2_set_sysname() to provide the necessary buffers.
*/
#if !defined SNMP_LWIP_MIB2_SYSNAME || defined __DOXYGEN__
#define SNMP_LWIP_MIB2_SYSNAME "FQDN-unk"
#endif
/**
* Value return for sysContact field of MIB2.
* To make sysContact field settable, call snmp_mib2_set_syscontact() to provide the necessary buffers.
*/
#if !defined SNMP_LWIP_MIB2_SYSCONTACT || defined __DOXYGEN__
#define SNMP_LWIP_MIB2_SYSCONTACT ""
#endif
/**
* Value return for sysLocation field of MIB2.
* To make sysLocation field settable, call snmp_mib2_set_syslocation() to provide the necessary buffers.
*/
#if !defined SNMP_LWIP_MIB2_SYSLOCATION || defined __DOXYGEN__
#define SNMP_LWIP_MIB2_SYSLOCATION ""
#endif
/**
* This value is used to limit the repetitions processed in GetBulk requests (value == 0 means no limitation).
* This may be useful to limit the load for a single request.
* According to SNMP RFC 1905 it is allowed to not return all requested variables from a GetBulk request if system load would be too high.
* so the effect is that the client will do more requests to gather all data.
* For the stack this could be useful in case that SNMP processing is done in TCP/IP thread. In this situation a request with many
* repetitions could block the thread for a longer time. Setting limit here will keep the stack more responsive.
*/
#if !defined SNMP_LWIP_GETBULK_MAX_REPETITIONS || defined __DOXYGEN__
#define SNMP_LWIP_GETBULK_MAX_REPETITIONS 0
#endif
/**
* @}
*/
/*
------------------------------------
---------- SNMPv3 options ----------
------------------------------------
*/
/**
* LWIP_SNMP_V3==1: This enables EXPERIMENTAL SNMPv3 support. LWIP_SNMP must
* also be enabled.
* THIS IS UNDER DEVELOPMENT AND SHOULD NOT BE ENABLED IN PRODUCTS.
*/
#ifndef LWIP_SNMP_V3
#define LWIP_SNMP_V3 0
#endif
#ifndef LWIP_SNMP_V3_MBEDTLS
#define LWIP_SNMP_V3_MBEDTLS LWIP_SNMP_V3
#endif
#ifndef LWIP_SNMP_V3_CRYPTO
#define LWIP_SNMP_V3_CRYPTO LWIP_SNMP_V3_MBEDTLS
#endif
#ifndef LWIP_SNMP_CONFIGURE_VERSIONS
#define LWIP_SNMP_CONFIGURE_VERSIONS 0
#endif
#endif /* LWIP_HDR_SNMP_OPTS_H */
@@ -0,0 +1,113 @@
/**
* @file
* SNMP server MIB API to implement scalar nodes
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Martin Hentschel <info@cl-soft.de>
*
*/
#ifndef LWIP_HDR_APPS_SNMP_SCALAR_H
#define LWIP_HDR_APPS_SNMP_SCALAR_H
#include "lwip/apps/snmp_opts.h"
#include "lwip/apps/snmp_core.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
/** basic scalar node */
struct snmp_scalar_node
{
/** inherited "base class" members */
struct snmp_leaf_node node;
u8_t asn1_type;
snmp_access_t access;
node_instance_get_value_method get_value;
node_instance_set_test_method set_test;
node_instance_set_value_method set_value;
};
snmp_err_t snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
snmp_err_t snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
#define SNMP_SCALAR_CREATE_NODE(oid, access, asn1_type, get_value_method, set_test_method, set_value_method) \
{{{ SNMP_NODE_SCALAR, (oid) }, \
snmp_scalar_get_instance, \
snmp_scalar_get_next_instance }, \
(asn1_type), (access), (get_value_method), (set_test_method), (set_value_method) }
#define SNMP_SCALAR_CREATE_NODE_READONLY(oid, asn1_type, get_value_method) SNMP_SCALAR_CREATE_NODE(oid, SNMP_NODE_INSTANCE_READ_ONLY, asn1_type, get_value_method, NULL, NULL)
/** scalar array node - a tree node which contains scalars only as children */
struct snmp_scalar_array_node_def
{
u32_t oid;
u8_t asn1_type;
snmp_access_t access;
};
typedef s16_t (*snmp_scalar_array_get_value_method)(const struct snmp_scalar_array_node_def*, void*);
typedef snmp_err_t (*snmp_scalar_array_set_test_method)(const struct snmp_scalar_array_node_def*, u16_t, void*);
typedef snmp_err_t (*snmp_scalar_array_set_value_method)(const struct snmp_scalar_array_node_def*, u16_t, void*);
/** basic scalar array node */
struct snmp_scalar_array_node
{
/** inherited "base class" members */
struct snmp_leaf_node node;
u16_t array_node_count;
const struct snmp_scalar_array_node_def* array_nodes;
snmp_scalar_array_get_value_method get_value;
snmp_scalar_array_set_test_method set_test;
snmp_scalar_array_set_value_method set_value;
};
snmp_err_t snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
snmp_err_t snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
#define SNMP_SCALAR_CREATE_ARRAY_NODE(oid, array_nodes, get_value_method, set_test_method, set_value_method) \
{{{ SNMP_NODE_SCALAR_ARRAY, (oid) }, \
snmp_scalar_array_get_instance, \
snmp_scalar_array_get_next_instance }, \
(u16_t)LWIP_ARRAYSIZE(array_nodes), (array_nodes), (get_value_method), (set_test_method), (set_value_method) }
#endif /* LWIP_SNMP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNMP_SCALAR_H */
@@ -0,0 +1,32 @@
/*
Generated by LwipMibCompiler
*/
#ifndef LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H
#define LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H
#include "lwip/apps/snmp_opts.h"
#if LWIP_SNMP
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "lwip/apps/snmp_core.h"
extern const struct snmp_obj_id usmNoAuthProtocol;
extern const struct snmp_obj_id usmHMACMD5AuthProtocol;
extern const struct snmp_obj_id usmHMACSHAAuthProtocol;
extern const struct snmp_obj_id usmNoPrivProtocol;
extern const struct snmp_obj_id usmDESPrivProtocol;
extern const struct snmp_obj_id usmAESPrivProtocol;
extern const struct snmp_mib snmpframeworkmib;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LWIP_SNMP */
#endif /* LWIP_HDR_APPS_SNMP_FRAMEWORK_MIB_H */
@@ -0,0 +1,24 @@
/*
Generated by LwipMibCompiler
*/
#ifndef LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H
#define LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H
#include "lwip/apps/snmp_opts.h"
#if LWIP_SNMP
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "lwip/apps/snmp_core.h"
extern const struct snmp_mib snmpusmmib;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* LWIP_SNMP */
#endif /* LWIP_HDR_APPS_SNMP_USER_BASED_SM_MIB_H */
@@ -0,0 +1,134 @@
/**
* @file
* SNMP server MIB API to implement table nodes
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Martin Hentschel <info@cl-soft.de>
*
*/
#ifndef LWIP_HDR_APPS_SNMP_TABLE_H
#define LWIP_HDR_APPS_SNMP_TABLE_H
#include "lwip/apps/snmp_opts.h"
#include "lwip/apps/snmp_core.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
/** default (customizable) read/write table */
struct snmp_table_col_def
{
u32_t index;
u8_t asn1_type;
snmp_access_t access;
};
/** table node */
struct snmp_table_node
{
/** inherited "base class" members */
struct snmp_leaf_node node;
u16_t column_count;
const struct snmp_table_col_def* columns;
snmp_err_t (*get_cell_instance)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance);
snmp_err_t (*get_next_cell_instance)(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance);
/** returns object value for the given object identifier */
node_instance_get_value_method get_value;
/** tests length and/or range BEFORE setting */
node_instance_set_test_method set_test;
/** sets object value, only called when set_test() was successful */
node_instance_set_value_method set_value;
};
snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
#define SNMP_TABLE_CREATE(oid, columns, get_cell_instance_method, get_next_cell_instance_method, get_value_method, set_test_method, set_value_method) \
{{{ SNMP_NODE_TABLE, (oid) }, \
snmp_table_get_instance, \
snmp_table_get_next_instance }, \
(u16_t)LWIP_ARRAYSIZE(columns), (columns), \
(get_cell_instance_method), (get_next_cell_instance_method), \
(get_value_method), (set_test_method), (set_value_method)}
#define SNMP_TABLE_GET_COLUMN_FROM_OID(oid) ((oid)[1]) /* first array value is (fixed) row entry (fixed to 1) and 2nd value is column, follow3ed by instance */
/** simple read-only table */
typedef enum {
SNMP_VARIANT_VALUE_TYPE_U32,
SNMP_VARIANT_VALUE_TYPE_S32,
SNMP_VARIANT_VALUE_TYPE_PTR,
SNMP_VARIANT_VALUE_TYPE_CONST_PTR
} snmp_table_column_data_type_t;
struct snmp_table_simple_col_def
{
u32_t index;
u8_t asn1_type;
snmp_table_column_data_type_t data_type; /* depending of what union member is used to store the value*/
};
/** simple read-only table node */
struct snmp_table_simple_node
{
/* inherited "base class" members */
struct snmp_leaf_node node;
u16_t column_count;
const struct snmp_table_simple_col_def* columns;
snmp_err_t (*get_cell_value)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len);
snmp_err_t (*get_next_cell_instance_and_value)(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len);
};
snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
#define SNMP_TABLE_CREATE_SIMPLE(oid, columns, get_cell_value_method, get_next_cell_instance_and_value_method) \
{{{ SNMP_NODE_TABLE, (oid) }, \
snmp_table_simple_get_instance, \
snmp_table_simple_get_next_instance }, \
(u16_t)LWIP_ARRAYSIZE(columns), (columns), (get_cell_value_method), (get_next_cell_instance_and_value_method) }
s16_t snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value);
s16_t snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value);
s16_t snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value);
#endif /* LWIP_SNMP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNMP_TABLE_H */
@@ -0,0 +1,114 @@
/**
* @file
* SNMP server MIB API to implement thread synchronization
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Dirk Ziegelmeier <dziegel@gmx.de>
*
*/
#ifndef LWIP_HDR_APPS_SNMP_THREADSYNC_H
#define LWIP_HDR_APPS_SNMP_THREADSYNC_H
#include "lwip/apps/snmp_opts.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
#include "lwip/apps/snmp_core.h"
#include "lwip/sys.h"
typedef void (*snmp_threadsync_called_fn)(void* arg);
typedef void (*snmp_threadsync_synchronizer_fn)(snmp_threadsync_called_fn fn, void* arg);
/** Thread sync runtime data. For internal usage only. */
struct threadsync_data
{
union {
snmp_err_t err;
s16_t s16;
} retval;
union {
const u32_t *root_oid;
void *value;
} arg1;
union {
u8_t root_oid_len;
u16_t len;
} arg2;
const struct snmp_threadsync_node *threadsync_node;
struct snmp_node_instance proxy_instance;
};
/** Thread sync instance. Needed EXCATLY once for every thread to be synced into. */
struct snmp_threadsync_instance
{
sys_sem_t sem;
sys_mutex_t sem_usage_mutex;
snmp_threadsync_synchronizer_fn sync_fn;
struct threadsync_data data;
};
/** SNMP thread sync proxy leaf node */
struct snmp_threadsync_node
{
/* inherited "base class" members */
struct snmp_leaf_node node;
const struct snmp_leaf_node *target;
struct snmp_threadsync_instance *instance;
};
snmp_err_t snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
snmp_err_t snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance);
/** Create thread sync proxy node */
#define SNMP_CREATE_THREAD_SYNC_NODE(oid, target_leaf_node, threadsync_instance) \
{{{ SNMP_NODE_THREADSYNC, (oid) }, \
snmp_threadsync_get_instance, \
snmp_threadsync_get_next_instance }, \
(target_leaf_node), \
(threadsync_instance) }
/** Create thread sync instance data */
void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn);
#endif /* LWIP_SNMP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNMP_THREADSYNC_H */
@@ -0,0 +1,114 @@
/**
* @file
* Additional SNMPv3 functionality RFC3414 and RFC3826.
*/
/*
* Copyright (c) 2016 Elias Oenal.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* Author: Elias Oenal <lwip@eliasoenal.com>
*/
#ifndef LWIP_HDR_APPS_SNMP_V3_H
#define LWIP_HDR_APPS_SNMP_V3_H
#include "lwip/apps/snmp_opts.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_SNMP && LWIP_SNMP_V3
typedef enum
{
SNMP_V3_AUTH_ALGO_INVAL = 0,
SNMP_V3_AUTH_ALGO_MD5 = 1,
SNMP_V3_AUTH_ALGO_SHA = 2
} snmpv3_auth_algo_t;
typedef enum
{
SNMP_V3_PRIV_ALGO_INVAL = 0,
SNMP_V3_PRIV_ALGO_DES = 1,
SNMP_V3_PRIV_ALGO_AES = 2
} snmpv3_priv_algo_t;
typedef enum
{
SNMP_V3_USER_STORAGETYPE_OTHER = 1,
SNMP_V3_USER_STORAGETYPE_VOLATILE = 2,
SNMP_V3_USER_STORAGETYPE_NONVOLATILE = 3,
SNMP_V3_USER_STORAGETYPE_PERMANENT = 4,
SNMP_V3_USER_STORAGETYPE_READONLY = 5
} snmpv3_user_storagetype_t;
/*
* The following callback functions must be implemented by the application.
* There is a dummy implementation in snmpv3_dummy.c.
*/
void snmpv3_get_engine_id(const char **id, u8_t *len);
err_t snmpv3_set_engine_id(const char* id, u8_t len);
u32_t snmpv3_get_engine_boots(void);
void snmpv3_set_engine_boots(u32_t boots);
u32_t snmpv3_get_engine_time(void);
void snmpv3_reset_engine_time(void);
err_t snmpv3_get_user(const char* username, snmpv3_auth_algo_t *auth_algo, u8_t *auth_key, snmpv3_priv_algo_t *priv_algo, u8_t *priv_key);
u8_t snmpv3_get_amount_of_users(void);
err_t snmpv3_get_user_storagetype(const char *username, snmpv3_user_storagetype_t *storagetype);
err_t snmpv3_get_username(char *username, u8_t index);
/* The following functions are provided by the SNMPv3 agent */
void snmpv3_engine_id_changed(void);
s32_t snmpv3_get_engine_time_internal(void);
void snmpv3_password_to_key_md5(
const u8_t *password, /* IN */
size_t passwordlen, /* IN */
const u8_t *engineID, /* IN - pointer to snmpEngineID */
u8_t engineLength, /* IN - length of snmpEngineID */
u8_t *key); /* OUT - pointer to caller 16-octet buffer */
void snmpv3_password_to_key_sha(
const u8_t *password, /* IN */
size_t passwordlen, /* IN */
const u8_t *engineID, /* IN - pointer to snmpEngineID */
u8_t engineLength, /* IN - length of snmpEngineID */
u8_t *key); /* OUT - pointer to caller 20-octet buffer */
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNMP_V3_H */
@@ -0,0 +1,80 @@
/**
* @file
* SNTP client API
*/
/*
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Frédéric Bernon, Simon Goldschmidt
*
*/
#ifndef LWIP_HDR_APPS_SNTP_H
#define LWIP_HDR_APPS_SNTP_H
#include "lwip/apps/sntp_opts.h"
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
/* SNTP operating modes: default is to poll using unicast.
The mode has to be set before calling sntp_init(). */
#define SNTP_OPMODE_POLL 0
#define SNTP_OPMODE_LISTENONLY 1
void sntp_setoperatingmode(u8_t operating_mode);
u8_t sntp_getoperatingmode(void);
void sntp_init(void);
void sntp_stop(void);
u8_t sntp_enabled(void);
void sntp_setserver(u8_t idx, const ip_addr_t *addr);
const ip_addr_t* sntp_getserver(u8_t idx);
#if SNTP_MONITOR_SERVER_REACHABILITY
u8_t sntp_getreachability(u8_t idx);
#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
#if SNTP_SERVER_DNS
void sntp_setservername(u8_t idx, const char *server);
const char *sntp_getservername(u8_t idx);
#endif /* SNTP_SERVER_DNS */
#if SNTP_GET_SERVERS_FROM_DHCP
void sntp_servermode_dhcp(int set_servers_from_dhcp);
#else /* SNTP_GET_SERVERS_FROM_DHCP */
#define sntp_servermode_dhcp(x)
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNTP_H */
@@ -0,0 +1,209 @@
/**
* @file
* SNTP client options list
*/
/*
* Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Frédéric Bernon, Simon Goldschmidt
*
*/
#ifndef LWIP_HDR_APPS_SNTP_OPTS_H
#define LWIP_HDR_APPS_SNTP_OPTS_H
#include "lwip/opt.h"
#include "lwip/prot/iana.h"
/**
* @defgroup sntp_opts Options
* @ingroup sntp
* @{
*/
/** SNTP macro to change system time in seconds
* Define SNTP_SET_SYSTEM_TIME_US(sec, us) to set the time in microseconds
* instead of this one if you need the additional precision. Alternatively,
* define SNTP_SET_SYSTEM_TIME_NTP(sec, frac) in order to work with native
* NTP timestamps instead.
*/
#if !defined SNTP_SET_SYSTEM_TIME || defined __DOXYGEN__
#define SNTP_SET_SYSTEM_TIME(sec) LWIP_UNUSED_ARG(sec)
#endif
/** The maximum number of SNTP servers that can be set */
#if !defined SNTP_MAX_SERVERS || defined __DOXYGEN__
#define SNTP_MAX_SERVERS LWIP_DHCP_MAX_NTP_SERVERS
#endif
/** Set this to 1 to implement the callback function called by dhcp when
* NTP servers are received. */
#if !defined SNTP_GET_SERVERS_FROM_DHCP || defined __DOXYGEN__
#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV
#endif
/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers
* One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
* \#define SNTP_SERVER_ADDRESS "pool.ntp.org"
*/
#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__
#define SNTP_SERVER_DNS 0
#endif
/**
* SNTP_DEBUG: Enable debugging for SNTP.
*/
#if !defined SNTP_DEBUG || defined __DOXYGEN__
#define SNTP_DEBUG LWIP_DBG_OFF
#endif
/** SNTP server port */
#if !defined SNTP_PORT || defined __DOXYGEN__
#define SNTP_PORT LWIP_IANA_PORT_SNTP
#endif
/** Sanity check:
* Define this to
* - 0 to turn off sanity checks (default; smaller code)
* - >= 1 to check address and port of the response packet to ensure the
* response comes from the server we sent the request to.
* - >= 2 to check returned Originate Timestamp against Transmit Timestamp
* sent to the server (to ensure response to older request).
* - >= 3 @todo: discard reply if any of the VN, Stratum, or Transmit Timestamp
* fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast).
* - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each
* greater than or equal to 0 and less than infinity, where infinity is
* currently a cozy number like one second. This check avoids using a
* server whose synchronization source has expired for a very long time.
*/
#if !defined SNTP_CHECK_RESPONSE || defined __DOXYGEN__
#define SNTP_CHECK_RESPONSE 0
#endif
/** Enable round-trip delay compensation.
* Compensate for the round-trip delay by calculating the clock offset from
* the originate, receive, transmit and destination timestamps, as per RFC.
*
* The calculation requires compiler support for 64-bit integers. Also, either
* SNTP_SET_SYSTEM_TIME_US or SNTP_SET_SYSTEM_TIME_NTP has to be implemented
* for setting the system clock with sub-second precision. Likewise, either
* SNTP_GET_SYSTEM_TIME or SNTP_GET_SYSTEM_TIME_NTP needs to be implemented
* with sub-second precision.
*
* Although not strictly required, it makes sense to combine this option with
* SNTP_CHECK_RESPONSE >= 2 for sanity-checking of the received timestamps.
* Also, in order for the round-trip calculation to work, the difference
* between the local clock and the NTP server clock must not be larger than
* about 34 years. If that limit is exceeded, the implementation will fall back
* to setting the clock without compensation. In order to ensure that the local
* clock is always within the permitted range for compensation, even at first
* try, it may be necessary to store at least the current year in non-volatile
* memory.
*/
#if !defined SNTP_COMP_ROUNDTRIP || defined __DOXYGEN__
#define SNTP_COMP_ROUNDTRIP 0
#endif
/** According to the RFC, this shall be a random delay
* between 1 and 5 minutes (in milliseconds) to prevent load peaks.
* This can be defined to a random generation function,
* which must return the delay in milliseconds as u32_t.
* Turned off by default.
*/
#if !defined SNTP_STARTUP_DELAY || defined __DOXYGEN__
#ifdef LWIP_RAND
#define SNTP_STARTUP_DELAY 1
#else
#define SNTP_STARTUP_DELAY 0
#endif
#endif
/** If you want the startup delay to be a function, define this
* to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1.
*/
#if !defined SNTP_STARTUP_DELAY_FUNC || defined __DOXYGEN__
#define SNTP_STARTUP_DELAY_FUNC (LWIP_RAND() % 5000)
#endif
/** SNTP receive timeout - in milliseconds
* Also used as retry timeout - this shouldn't be too low.
* Default is 15 seconds. Must not be beolw 15 seconds by specification (i.e. 15000)
*/
#if !defined SNTP_RECV_TIMEOUT || defined __DOXYGEN__
#define SNTP_RECV_TIMEOUT 15000
#endif
/** SNTP update delay - in milliseconds
* Default is 1 hour. Must not be beolw 60 seconds by specification (i.e. 60000)
*/
#if !defined SNTP_UPDATE_DELAY || defined __DOXYGEN__
#define SNTP_UPDATE_DELAY 3600000
#endif
/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2
* to send in request and compare in response. Also used for round-trip
* delay compensation if SNTP_COMP_ROUNDTRIP != 0.
* Alternatively, define SNTP_GET_SYSTEM_TIME_NTP(sec, frac) in order to
* work with native NTP timestamps instead.
*/
#if !defined SNTP_GET_SYSTEM_TIME || defined __DOXYGEN__
#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0)
#endif
/** Default retry timeout (in milliseconds) if the response
* received is invalid.
* This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached.
*/
#if !defined SNTP_RETRY_TIMEOUT || defined __DOXYGEN__
#define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT
#endif
/** Maximum retry timeout (in milliseconds). */
#if !defined SNTP_RETRY_TIMEOUT_MAX || defined __DOXYGEN__
#define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10)
#endif
/** Increase retry timeout with every retry sent
* Default is on to conform to RFC.
*/
#if !defined SNTP_RETRY_TIMEOUT_EXP || defined __DOXYGEN__
#define SNTP_RETRY_TIMEOUT_EXP 1
#endif
/** Keep a reachability shift register per server
* Default is on to conform to RFC.
*/
#if !defined SNTP_MONITOR_SERVER_REACHABILITY || defined __DOXYGEN__
#define SNTP_MONITOR_SERVER_REACHABILITY 1
#endif
/**
* @}
*/
#endif /* LWIP_HDR_APPS_SNTP_OPTS_H */
@@ -0,0 +1,106 @@
/**
*
* @file tftp_opts.h
*
* @author Logan Gunthorpe <logang@deltatee.com>
*
* @brief Trivial File Transfer Protocol (RFC 1350) implementation options
*
* Copyright (c) Deltatee Enterprises Ltd. 2013
* All rights reserved.
*
*/
/*
* Redistribution and use in source and binary forms, with or without
* modification,are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Logan Gunthorpe <logang@deltatee.com>
*
*/
#ifndef LWIP_HDR_APPS_TFTP_OPTS_H
#define LWIP_HDR_APPS_TFTP_OPTS_H
#include "lwip/opt.h"
#include "lwip/prot/iana.h"
/**
* @defgroup tftp_opts Options
* @ingroup tftp
* @{
*/
/**
* Enable TFTP debug messages
*/
#if !defined TFTP_DEBUG || defined __DOXYGEN__
#define TFTP_DEBUG LWIP_DBG_OFF
#endif
/**
* TFTP server port
*/
#if !defined TFTP_PORT || defined __DOXYGEN__
#define TFTP_PORT LWIP_IANA_PORT_TFTP
#endif
/**
* TFTP timeout
*/
#if !defined TFTP_TIMEOUT_MSECS || defined __DOXYGEN__
#define TFTP_TIMEOUT_MSECS 10000
#endif
/**
* Max. number of retries when a file is read from server
*/
#if !defined TFTP_MAX_RETRIES || defined __DOXYGEN__
#define TFTP_MAX_RETRIES 5
#endif
/**
* TFTP timer cyclic interval
*/
#if !defined TFTP_TIMER_MSECS || defined __DOXYGEN__
#define TFTP_TIMER_MSECS (TFTP_TIMEOUT_MSECS / 10)
#endif
/**
* Max. length of TFTP filename
*/
#if !defined TFTP_MAX_FILENAME_LEN || defined __DOXYGEN__
#define TFTP_MAX_FILENAME_LEN 20
#endif
/**
* Max. length of TFTP mode
*/
#if !defined TFTP_MAX_MODE_LEN || defined __DOXYGEN__
#define TFTP_MAX_MODE_LEN 7
#endif
/**
* @}
*/
#endif /* LWIP_HDR_APPS_TFTP_OPTS_H */
@@ -0,0 +1,95 @@
/**
*
* @file tftp_server.h
*
* @author Logan Gunthorpe <logang@deltatee.com>
*
* @brief Trivial File Transfer Protocol (RFC 1350)
*
* Copyright (c) Deltatee Enterprises Ltd. 2013
* All rights reserved.
*
*/
/*
* Redistribution and use in source and binary forms, with or without
* modification,are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Author: Logan Gunthorpe <logang@deltatee.com>
*
*/
#ifndef LWIP_HDR_APPS_TFTP_SERVER_H
#define LWIP_HDR_APPS_TFTP_SERVER_H
#include "lwip/apps/tftp_opts.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @ingroup tftp
* TFTP context containing callback functions for TFTP transfers
*/
struct tftp_context {
/**
* Open file for read/write.
* @param fname Filename
* @param mode Mode string from TFTP RFC 1350 (netascii, octet, mail)
* @param write Flag indicating read (0) or write (!= 0) access
* @returns File handle supplied to other functions
*/
void* (*open)(const char* fname, const char* mode, u8_t write);
/**
* Close file handle
* @param handle File handle returned by open()
*/
void (*close)(void* handle);
/**
* Read from file
* @param handle File handle returned by open()
* @param buf Target buffer to copy read data to
* @param bytes Number of bytes to copy to buf
* @returns &gt;= 0: Success; &lt; 0: Error
*/
int (*read)(void* handle, void* buf, int bytes);
/**
* Write to file
* @param handle File handle returned by open()
* @param pbuf PBUF adjusted such that payload pointer points
* to the beginning of write data. In other words,
* TFTP headers are stripped off.
* @returns &gt;= 0: Success; &lt; 0: Error
*/
int (*write)(void* handle, struct pbuf* p);
};
err_t tftp_init(const struct tftp_context* ctx);
void tftp_cleanup(void);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_TFTP_SERVER_H */
@@ -0,0 +1,393 @@
/**
* @file
* Support for different processor and compiler architectures
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_ARCH_H
#define LWIP_HDR_ARCH_H
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
#endif
#include "arch/cc.h"
/**
* @defgroup compiler_abstraction Compiler/platform abstraction
* @ingroup sys_layer
* All defines related to this section must not be placed in lwipopts.h,
* but in arch/cc.h!
* If the compiler does not provide memset() this file must include a
* definition of it, or include a file which defines it.
* These options cannot be \#defined in lwipopts.h since they are not options
* of lwIP itself, but options of the lwIP port to your system.
* @{
*/
/** Define the byte order of the system.
* Needed for conversion of network data to host byte order.
* Allowed values: LITTLE_ENDIAN and BIG_ENDIAN
*/
#ifndef BYTE_ORDER
#define BYTE_ORDER LITTLE_ENDIAN
#endif
/** Define random number generator function of your system */
#ifdef __DOXYGEN__
#define LWIP_RAND() ((u32_t)rand())
#endif
/** Platform specific diagnostic output.\n
* Note the default implementation pulls in printf, which may
* in turn pull in a lot of standard libary code. In resource-constrained
* systems, this should be defined to something less resource-consuming.
*/
#ifndef LWIP_PLATFORM_DIAG
#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0)
#include <stdio.h>
#include <stdlib.h>
#endif
/** Platform specific assertion handling.\n
* Note the default implementation pulls in printf, fflush and abort, which may
* in turn pull in a lot of standard libary code. In resource-constrained
* systems, this should be defined to something less resource-consuming.
*/
#ifndef LWIP_PLATFORM_ASSERT
#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \
x, __LINE__, __FILE__); fflush(NULL); abort();} while(0)
#include <stdio.h>
#include <stdlib.h>
#endif
/** Define this to 1 in arch/cc.h of your port if you do not want to
* include stddef.h header to get size_t. You need to typedef size_t
* by yourself in this case.
*/
#ifndef LWIP_NO_STDDEF_H
#define LWIP_NO_STDDEF_H 0
#endif
#if !LWIP_NO_STDDEF_H
#include <stddef.h> /* for size_t */
#endif
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
* the stdint.h header. You need to typedef the generic types listed in
* lwip/arch.h yourself in this case (u8_t, u16_t...).
*/
#ifndef LWIP_NO_STDINT_H
#define LWIP_NO_STDINT_H 0
#endif
/* Define generic types used in lwIP */
#if !LWIP_NO_STDINT_H
#include <stdint.h>
/* stdint.h is C99 which should also provide support for 64-bit integers */
#if !defined(LWIP_HAVE_INT64) && defined(UINT64_MAX)
#define LWIP_HAVE_INT64 1
#endif
typedef uint8_t u8_t;
typedef int8_t s8_t;
typedef uint16_t u16_t;
typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
#if LWIP_HAVE_INT64
typedef uint64_t u64_t;
typedef int64_t s64_t;
#endif
typedef uintptr_t mem_ptr_t;
#endif
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
* the inttypes.h header. You need to define the format strings listed in
* lwip/arch.h yourself in this case (X8_F, U16_F...).
*/
#ifndef LWIP_NO_INTTYPES_H
#define LWIP_NO_INTTYPES_H 0
#endif
/* Define (sn)printf formatters for these lwIP types */
#if !LWIP_NO_INTTYPES_H
#include <inttypes.h>
#ifndef X8_F
#define X8_F "02" PRIx8
#endif
#ifndef U16_F
#define U16_F PRIu16
#endif
#ifndef S16_F
#define S16_F PRId16
#endif
#ifndef X16_F
#define X16_F PRIx16
#endif
#ifndef U32_F
#define U32_F PRIu32
#endif
#ifndef S32_F
#define S32_F PRId32
#endif
#ifndef X32_F
#define X32_F PRIx32
#endif
#ifndef SZT_F
#define SZT_F PRIuPTR
#endif
#endif
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
* the limits.h header. You need to define the type limits yourself in this case
* (e.g. INT_MAX, SSIZE_MAX).
*/
#ifndef LWIP_NO_LIMITS_H
#define LWIP_NO_LIMITS_H 0
#endif
/* Include limits.h? */
#if !LWIP_NO_LIMITS_H
#include <limits.h>
#endif
/* Do we need to define ssize_t? This is a compatibility hack:
* Unfortunately, this type seems to be unavailable on some systems (even if
* sys/types or unistd.h are available).
* Being like that, we define it to 'int' if SSIZE_MAX is not defined.
*/
#ifdef SSIZE_MAX
/* If SSIZE_MAX is defined, unistd.h should provide the type as well */
#ifndef LWIP_NO_UNISTD_H
#define LWIP_NO_UNISTD_H 0
#endif
#if !LWIP_NO_UNISTD_H
#include <unistd.h>
#endif
#else /* SSIZE_MAX */
typedef int ssize_t;
#define SSIZE_MAX INT_MAX
#endif /* SSIZE_MAX */
/* some maximum values needed in lwip code */
#define LWIP_UINT32_MAX 0xffffffff
/** Define this to 1 in arch/cc.h of your port if your compiler does not provide
* the ctype.h header. If ctype.h is available, a few character functions
* are mapped to the appropriate functions (lwip_islower, lwip_isdigit...), if
* not, a private implementation is provided.
*/
#ifndef LWIP_NO_CTYPE_H
#define LWIP_NO_CTYPE_H 0
#endif
#if LWIP_NO_CTYPE_H
#define lwip_in_range(c, lo, up) ((u8_t)(c) >= (lo) && (u8_t)(c) <= (up))
#define lwip_isdigit(c) lwip_in_range((c), '0', '9')
#define lwip_isxdigit(c) (lwip_isdigit(c) || lwip_in_range((c), 'a', 'f') || lwip_in_range((c), 'A', 'F'))
#define lwip_islower(c) lwip_in_range((c), 'a', 'z')
#define lwip_isspace(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\v')
#define lwip_isupper(c) lwip_in_range((c), 'A', 'Z')
#define lwip_tolower(c) (lwip_isupper(c) ? (c) - 'A' + 'a' : c)
#define lwip_toupper(c) (lwip_islower(c) ? (c) - 'a' + 'A' : c)
#else
#include <ctype.h>
#define lwip_isdigit(c) isdigit((unsigned char)(c))
#define lwip_isxdigit(c) isxdigit((unsigned char)(c))
#define lwip_islower(c) islower((unsigned char)(c))
#define lwip_isspace(c) isspace((unsigned char)(c))
#define lwip_isupper(c) isupper((unsigned char)(c))
#define lwip_tolower(c) tolower((unsigned char)(c))
#define lwip_toupper(c) toupper((unsigned char)(c))
#endif
/** C++ const_cast<target_type>(val) equivalent to remove constness from a value (GCC -Wcast-qual) */
#ifndef LWIP_CONST_CAST
#define LWIP_CONST_CAST(target_type, val) ((target_type)((ptrdiff_t)val))
#endif
/** Get rid of alignment cast warnings (GCC -Wcast-align) */
#ifndef LWIP_ALIGNMENT_CAST
#define LWIP_ALIGNMENT_CAST(target_type, val) LWIP_CONST_CAST(target_type, val)
#endif
/** Get rid of warnings related to pointer-to-numeric and vice-versa casts,
* e.g. "conversion from 'u8_t' to 'void *' of greater size"
*/
#ifndef LWIP_PTR_NUMERIC_CAST
#define LWIP_PTR_NUMERIC_CAST(target_type, val) LWIP_CONST_CAST(target_type, val)
#endif
/** Avoid warnings/errors related to implicitly casting away packed attributes by doing a explicit cast */
#ifndef LWIP_PACKED_CAST
#define LWIP_PACKED_CAST(target_type, val) LWIP_CONST_CAST(target_type, val)
#endif
/** Allocates a memory buffer of specified size that is of sufficient size to align
* its start address using LWIP_MEM_ALIGN.
* You can declare your own version here e.g. to enforce alignment without adding
* trailing padding bytes (see LWIP_MEM_ALIGN_BUFFER) or your own section placement
* requirements.\n
* e.g. if you use gcc and need 32 bit alignment:\n
* \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[size] \_\_attribute\_\_((aligned(4)))\n
* or more portable:\n
* \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u32_t variable_name[(size + sizeof(u32_t) - 1) / sizeof(u32_t)]
*/
#ifndef LWIP_DECLARE_MEMORY_ALIGNED
#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)]
#endif
/** Calculate memory size for an aligned buffer - returns the next highest
* multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and
* LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4).
*/
#ifndef LWIP_MEM_ALIGN_SIZE
#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1U) & ~(MEM_ALIGNMENT-1U))
#endif
/** Calculate safe memory size for an aligned buffer when using an unaligned
* type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the
* start (e.g. if buffer is u8_t[] and actual data will be u32_t*)
*/
#ifndef LWIP_MEM_ALIGN_BUFFER
#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1U))
#endif
/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT
* so that ADDR % MEM_ALIGNMENT == 0
*/
#ifndef LWIP_MEM_ALIGN
#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** Packed structs support.
* Placed BEFORE declaration of a packed struct.\n
* For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
* A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
*/
#ifndef PACK_STRUCT_BEGIN
#define PACK_STRUCT_BEGIN
#endif /* PACK_STRUCT_BEGIN */
/** Packed structs support.
* Placed AFTER declaration of a packed struct.\n
* For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
* A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
*/
#ifndef PACK_STRUCT_END
#define PACK_STRUCT_END
#endif /* PACK_STRUCT_END */
/** Packed structs support.
* Placed between end of declaration of a packed struct and trailing semicolon.\n
* For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
* A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
*/
#ifndef PACK_STRUCT_STRUCT
#if defined(__GNUC__) || defined(__clang__)
#define PACK_STRUCT_STRUCT __attribute__((packed))
#else
#define PACK_STRUCT_STRUCT
#endif
#endif /* PACK_STRUCT_STRUCT */
/** Packed structs support.
* Wraps u32_t and u16_t members.\n
* For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
* A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
*/
#ifndef PACK_STRUCT_FIELD
#define PACK_STRUCT_FIELD(x) x
#endif /* PACK_STRUCT_FIELD */
/** Packed structs support.
* Wraps u8_t members, where some compilers warn that packing is not necessary.\n
* For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
* A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
*/
#ifndef PACK_STRUCT_FLD_8
#define PACK_STRUCT_FLD_8(x) PACK_STRUCT_FIELD(x)
#endif /* PACK_STRUCT_FLD_8 */
/** Packed structs support.
* Wraps members that are packed structs themselves, where some compilers warn that packing is not necessary.\n
* For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
* A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
*/
#ifndef PACK_STRUCT_FLD_S
#define PACK_STRUCT_FLD_S(x) PACK_STRUCT_FIELD(x)
#endif /* PACK_STRUCT_FLD_S */
/** PACK_STRUCT_USE_INCLUDES==1: Packed structs support using \#include files before and after struct to be packed.\n
* The file included BEFORE the struct is "arch/bpstruct.h".\n
* The file included AFTER the struct is "arch/epstruct.h".\n
* This can be used to implement struct packing on MS Visual C compilers, see
* the Win32 port in the lwIP contrib repository for reference.
* For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n
* A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here.
*/
#ifdef __DOXYGEN__
#define PACK_STRUCT_USE_INCLUDES
#endif
/** Eliminates compiler warning about unused arguments (GCC -Wextra -Wunused). */
#ifndef LWIP_UNUSED_ARG
#define LWIP_UNUSED_ARG(x) (void)x
#endif /* LWIP_UNUSED_ARG */
/** LWIP_PROVIDE_ERRNO==1: Let lwIP provide ERRNO values and the 'errno' variable.
* If this is disabled, cc.h must either define 'errno', include <errno.h>,
* define LWIP_ERRNO_STDINCLUDE to get <errno.h> included or
* define LWIP_ERRNO_INCLUDE to <errno.h> or equivalent.
*/
#if defined __DOXYGEN__
#define LWIP_PROVIDE_ERRNO
#endif
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_ARCH_H */
@@ -0,0 +1,99 @@
/**
* @file
*
* AutoIP Automatic LinkLocal IP Configuration
*/
/*
*
* Copyright (c) 2007 Dominik Spies <kontakt@dspies.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* Author: Dominik Spies <kontakt@dspies.de>
*
* This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform
* with RFC 3927.
*
*/
#ifndef LWIP_HDR_AUTOIP_H
#define LWIP_HDR_AUTOIP_H
#include "lwip/opt.h"
#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */
#include "lwip/netif.h"
/* #include "lwip/udp.h" */
#include "lwip/etharp.h"
#ifdef __cplusplus
extern "C" {
#endif
/** AutoIP Timing */
#define AUTOIP_TMR_INTERVAL 100
#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL)
/** AutoIP state information per netif */
struct autoip
{
/** the currently selected, probed, announced or used LL IP-Address */
ip4_addr_t llipaddr;
/** current AutoIP state machine state */
u8_t state;
/** sent number of probes or announces, dependent on state */
u8_t sent_num;
/** ticks to wait, tick is AUTOIP_TMR_INTERVAL long */
u16_t ttw;
/** ticks until a conflict can be solved by defending */
u8_t lastconflict;
/** total number of probed/used Link Local IP-Addresses */
u8_t tried_llipaddr;
};
void autoip_set_struct(struct netif *netif, struct autoip *autoip);
/** Remove a struct autoip previously set to the netif using autoip_set_struct() */
#define autoip_remove_struct(netif) do { (netif)->autoip = NULL; } while (0)
err_t autoip_start(struct netif *netif);
err_t autoip_stop(struct netif *netif);
void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr);
void autoip_tmr(void);
void autoip_network_changed(struct netif *netif);
u8_t autoip_supplied_address(const struct netif *netif);
/* for lwIP internal use by ip4.c */
u8_t autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr);
#define netif_autoip_data(netif) ((struct autoip*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP))
#ifdef __cplusplus
}
#endif
#endif /* LWIP_IPV4 && LWIP_AUTOIP */
#endif /* LWIP_HDR_AUTOIP_H */
@@ -0,0 +1,161 @@
/**
* @file
* Debug messages infrastructure
*/
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef LWIP_HDR_DEBUG_H
#define LWIP_HDR_DEBUG_H
#include "lwip/arch.h"
#include "lwip/opt.h"
/**
* @defgroup debugging_levels LWIP_DBG_MIN_LEVEL and LWIP_DBG_TYPES_ON values
* @ingroup lwip_opts_debugmsg
* @{
*/
/** @name Debug level (LWIP_DBG_MIN_LEVEL)
* @{
*/
/** Debug level: ALL messages*/
#define LWIP_DBG_LEVEL_ALL 0x00
/** Debug level: Warnings. bad checksums, dropped packets, ... */
#define LWIP_DBG_LEVEL_WARNING 0x01
/** Debug level: Serious. memory allocation failures, ... */
#define LWIP_DBG_LEVEL_SERIOUS 0x02
/** Debug level: Severe */
#define LWIP_DBG_LEVEL_SEVERE 0x03
/**
* @}
*/
#define LWIP_DBG_MASK_LEVEL 0x03
/* compatibility define only */
#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL
/** @name Enable/disable debug messages completely (LWIP_DBG_TYPES_ON)
* @{
*/
/** flag for LWIP_DEBUGF to enable that debug message */
#define LWIP_DBG_ON 0x80U
/** flag for LWIP_DEBUGF to disable that debug message */
#define LWIP_DBG_OFF 0x00U
/**
* @}
*/
/** @name Debug message types (LWIP_DBG_TYPES_ON)
* @{
*/
/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */
#define LWIP_DBG_TRACE 0x40U
/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */
#define LWIP_DBG_STATE 0x20U
/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */
#define LWIP_DBG_FRESH 0x10U
/** flag for LWIP_DEBUGF to halt after printing this debug message */
#define LWIP_DBG_HALT 0x08U
/**
* @}
*/
/**
* @}
*/
/**
* @defgroup lwip_assertions Assertion handling
* @ingroup lwip_opts_debug
* @{
*/
/**
* LWIP_NOASSERT: Disable LWIP_ASSERT checks:
* To disable assertions define LWIP_NOASSERT in arch/cc.h.
*/
#ifdef __DOXYGEN__
#define LWIP_NOASSERT
#undef LWIP_NOASSERT
#endif
/**
* @}
*/
#ifndef LWIP_NOASSERT
#define LWIP_ASSERT(message, assertion) do { if (!(assertion)) { \
LWIP_PLATFORM_ASSERT(message); }} while(0)
#else /* LWIP_NOASSERT */
#define LWIP_ASSERT(message, assertion)
#endif /* LWIP_NOASSERT */
#ifndef LWIP_ERROR
#ifndef LWIP_NOASSERT
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message)
#elif defined LWIP_DEBUG
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message))
#else
#define LWIP_PLATFORM_ERROR(message)
#endif
/* if "expression" isn't true, then print "message" and execute "handler" expression */
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
LWIP_PLATFORM_ERROR(message); handler;}} while(0)
#endif /* LWIP_ERROR */
/** Enable debug message printing, but only if debug message type is enabled
* AND is of correct type AND is at least LWIP_DBG_LEVEL.
*/
#ifdef __DOXYGEN__
#define LWIP_DEBUG
#undef LWIP_DEBUG
#endif
#ifdef LWIP_DEBUG
#define LWIP_DEBUGF(debug, message) do { \
if ( \
((debug) & LWIP_DBG_ON) && \
((debug) & LWIP_DBG_TYPES_ON) && \
((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
LWIP_PLATFORM_DIAG(message); \
if ((debug) & LWIP_DBG_HALT) { \
while(1); \
} \
} \
} while(0)
#else /* LWIP_DEBUG */
#define LWIP_DEBUGF(debug, message)
#endif /* LWIP_DEBUG */
#endif /* LWIP_HDR_DEBUG_H */
Loaded 100 of 2425 files, more files were not shown because too many files have changed in this diff. Show more