diff options
| author | Andrew Leech <[email protected]> | 2025-05-27 15:06:05 +1000 |
|---|---|---|
| committer | Andrew Leech <[email protected]> | 2025-05-29 09:36:38 +1000 |
| commit | 5de4a23abe315ecc5f9387ced910f54e29e0e69e (patch) | |
| tree | 62b387c0addd059f67823fade738851d9f9d48b3 /src/class/net | |
| parent | 8f077f9295838d6a7e7a5151cb46605df14a630d (diff) | |
Add USB NCM link state control support
This adds the ability to dynamically control the network link state
for NCM devices. The host OS will see the network interface as
connected/disconnected based on the link state.
New API:
- tud_network_link_state(rhport, is_up): Set link up/down state
Example updates:
- Added button control to toggle link state
- Fixed LWIP integration to properly handle link state changes
- Added printf to show correct protocol (NCM vs RNDIS/ECM)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Diffstat (limited to 'src/class/net')
| -rw-r--r-- | src/class/net/ncm_device.c | 36 | ||||
| -rw-r--r-- | src/class/net/net_device.h | 5 |
2 files changed, 40 insertions, 1 deletions
diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index f9fda0698..02833c5f1 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -110,6 +110,7 @@ typedef struct { NOTIFICATION_DONE } notification_xmit_state; // state of notification transmission bool notification_xmit_is_running; // notification is currently transmitted + bool link_is_up; // current link state // misc bool tud_network_recv_renew_active; // tud_network_recv_renew() is active (avoid recursive invocations) @@ -218,7 +219,7 @@ static void notification_xmit(uint8_t rhport, bool force_next) { .direction = TUSB_DIR_IN }, .bRequest = CDC_NOTIF_NETWORK_CONNECTION, - .wValue = 1 /* Connected */, + .wValue = ncm_interface.link_is_up ? 1 : 0, /* Dynamic link state */ .wIndex = ncm_interface.itf_num, .wLength = 0, }, @@ -232,6 +233,7 @@ static void notification_xmit(uint8_t rhport, bool force_next) { ncm_interface.notification_xmit_is_running = true; } else { TU_LOG_DRV(" NOTIFICATION_FINISHED\n"); + ncm_interface.notification_xmit_is_running = false; } } // notification_xmit @@ -755,6 +757,32 @@ static void tud_network_recv_renew_r(uint8_t rhport) { tud_network_recv_renew(); } // tud_network_recv_renew +/** + * Set the link state and send notification to host + */ +void tud_network_link_state(uint8_t rhport, bool is_up) { + TU_LOG_DRV("tud_network_link_state(%d, %d)\n", rhport, is_up); + + if (ncm_interface.link_is_up == is_up) { + // No change in link state + return; + } + + ncm_interface.link_is_up = is_up; + + // Only send notification if we have an active data interface + if (ncm_interface.itf_data_alt != 1) { + TU_LOG_DRV(" link state notification skipped (interface not active)\n"); + return; + } + + // Reset notification state to send link state update + ncm_interface.notification_xmit_state = NOTIFICATION_CONNECTED; + + // Trigger notification transmission + notification_xmit(rhport, false); +} + //----------------------------------------------------------------------------- // // all the netd_*() stuff (interface TinyUSB -> driver) @@ -774,6 +802,12 @@ void netd_init(void) { for (int i = 0; i < RECV_NTB_N; ++i) { ncm_interface.recv_free_ntb[i] = &ncm_epbuf.recv[i].ntb; } + // Default link state - can be configured via CFG_TUD_NCM_DEFAULT_LINK_UP + #ifdef CFG_TUD_NCM_DEFAULT_LINK_UP + ncm_interface.link_is_up = CFG_TUD_NCM_DEFAULT_LINK_UP; + #else + ncm_interface.link_is_up = true; // Default to link up if not set. + #endif } // netd_init /** diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 4c9a92f2d..fff2623b7 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -87,6 +87,11 @@ void tud_network_init_cb(void); // TODO removed later since it is not part of tinyusb stack extern uint8_t tud_network_mac_address[6]; +//------------- NCM -------------// + +// Set the network link state (up/down) and notify the host +void tud_network_link_state(uint8_t rhport, bool is_up); + //--------------------------------------------------------------------+ // INTERNAL USBD-CLASS DRIVER API //--------------------------------------------------------------------+ |
