Skip to content

Comments

Dual mode#2

Open
squirelo wants to merge 22 commits intomasterfrom
dual-mode
Open

Dual mode#2
squirelo wants to merge 22 commits intomasterfrom
dual-mode

Conversation

@squirelo
Copy link
Owner

@squirelo squirelo commented Jun 23, 2025

Note

Adds BLE peripheral mode with a UART-based framed protocol to inject HID reports, plus a Web Bluetooth transmitter app to send gamepad data; reworks LED/status, USB HID queuing, and scanning/connection flows.

  • Firmware (Bluetooth/HID):
    • Dual Mode: Enable simultaneous BT_CENTRAL + BT_PERIPHERAL; conditionally run scan/host logic and peripheral advertising.
    • GATT/NUS Service: Define UART service/characteristics and CCC; handle writes via uart_write_cb.
    • Framed Protocol: Add SLIP-like framing with CRC32 (END/ESC) to parse packets and dispatch HID reports; validate PROTOCOL_VERSION, command, lengths.
    • Virtual HID Peripheral: Register/unregister a virtual interface (VIRTUAL_PERIPHERAL_INTERFACE), (re)parse descriptors by index, and forward received reports with report_id=1.
    • Advertising: Start/stop connectable advertising with retry/backoff work; restart after disconnect.
    • Conn Handling: Distinguish host vs peripheral roles; cleanup/refcounting; permissive LE params; avoid interface collision via conn_idx_to_interface.
    • LED/UX: New status/blink logic reflecting host/peripheral states; activity LED race fixes.
    • USB HID: Non-blocking TX queue + worker; callbacks kick sender; main loop no longer blocks on semaphores.
    • Scanning/Discovery: Scan only when host enabled; peers-only behavior preserved; security/discovery gated to host.
    • Config Tweaks: prj.conf adds CONFIG_BT_PERIPHERAL, CONFIG_BT_GATT_SERVICE_CHANGED, CONFIG_BT_GATT_DYNAMIC_DB, USB/HID tunings.
  • Web Transmitter (transmitter-ble-web/):
    • New App: index.html, code.js, crc.js implement a Web Bluetooth client using Nordic UART Service.
    • Input Sources: Virtual buttons/sticks UI and optional physical gamepad forwarding.
    • Protocol: Build framed packets with CRC32 and send via NUS; adjustable MTU-chunked writes.

Written by Cursor Bugbot for commit 054a045. This will update automatically on new commits. Configure here.

squirelo added 21 commits June 19, 2025 08:41
- Added packet structure definitions and handling for a new protocol.
- Introduced functions for processing received packets with SLIP-like framing.
- Updated peripheral mode initialization to reflect changes in descriptor handling.
- Modified advertising name to use the configured Bluetooth device name.
- Cleaned up and removed unused virtual gamepad descriptor code.
- Introduced a new JavaScript module for handling Bluetooth Low Energy (BLE) connections with a gamepad.
- Implemented virtual button states and event handlers for user interaction.
- Added functionality for connecting, disconnecting, and sending data to BLE devices.
- Included CRC32 checksum calculation for data integrity.
- Created an HTML interface for user controls and output display.
- Ensured compatibility with Web Bluetooth API and provided user feedback for connection status.
- Updated the Bluetooth firmware to support simultaneous host and peripheral modes.
- Introduced coordination flags to manage scanning and connection states between modes.
- Implemented LED status updates to reflect active modes and connections.
- Added JavaScript functionality for enabling physical gamepad forwarding in the web interface.
- Improved handling of gamepad input processing based on forwarding state.
- Updated HTML to include a toggle for enabling gamepad forwarding.
- Adjusted connection parameter handling in le_param_req to set interval_max based on interval_min.
- Removed redundant comments for clarity.
- Eliminated the `queue_outgoing_report`, `virtual_gamepad_clear_report`, and `virtual_gamepad_default_value` functions to streamline the code.
- Removed redundant comments to enhance code clarity.
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

uint8_t protocol_version = data[0];
uint8_t command = data[1];
uint8_t payload_length = data[2];
uint8_t descriptor_number = data[3];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Packet format mismatch between sender and receiver

The packet parsing in handle_received_packet expects field order [protocol_version, command, payload_length, descriptor_number], but the JavaScript sender in send_report transmits [protocol_version, descriptor_number, length, report_id]. This causes the receiver to interpret descriptor_number as command and check if it equals 7 (line 826), which will always fail since the JavaScript sends descriptor_number=2. The packet_t struct definition (lines 73-79) also contradicts the parsing logic, defining the second field as our_descriptor_number rather than command.

Additional Locations (1)

Fix in Cursor Fix in Web

break;
}
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Unhandled interface value silently drops messages

In usb_hid_tx_work_fn, when msg.interface is neither 0 nor 1, the message is dequeued from usb_hid_tx_q but not processed or requeued. The while loop continues to the next iteration, silently dropping the message without any error logging. While only interfaces 0 and 1 are currently used, an invalid interface value from a bug elsewhere would cause silent data loss with no diagnostic output.

Fix in Cursor Fix in Web

data[0] = 1; // protocol version
data[1] = 2; // descriptor number
data[2] = 8; // length
data[3] = 1; // report_id (now 1 to match virtual gamepad descriptor)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Protocol format mismatch between web and firmware

The web transmitter sends packet header bytes in order: protocol_version, descriptor_number, length, report_id, but the firmware expects: protocol_version, command, payload_length, descriptor_number. The firmware validates command == 7 at line 827, but receives descriptor_number (value 2) in that position, causing all packets to be rejected. This breaks communication between the web client and firmware.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant