Parcourir la source

Merge branch 'Bluetooth-WIP' into WIP2-Bluetooth

main
Kurt Eckhardt il y a 6 ans
Parent
révision
f01a82db42
5 fichiers modifiés avec 1579 ajouts et 8 suppressions
  1. +169
    -4
      USBHost_t36.h
  2. +1278
    -0
      bluetooth.cpp
  3. +4
    -2
      examples/Mouse/Mouse.ino
  4. +34
    -0
      joystick.cpp
  5. +94
    -2
      keyboard.cpp

+ 169
- 4
USBHost_t36.h Voir le fichier

@@ -56,7 +56,7 @@
// your best effort to read chapter 4 before asking USB questions!


//#define USBHOST_PRINT_DEBUG
#define USBHOST_PRINT_DEBUG

/************************************************/
/* Data Types */
@@ -522,6 +522,35 @@ protected:
Device_t *mydevice = NULL;
};


// Device drivers may inherit from this base class, if they wish to receive
// HID input like data from Bluetooth HID device.
class BluetoothController;

class BTHIDInput {
public:
operator bool() { return (btdevice != nullptr); }
uint16_t idVendor() { return (btdevice != nullptr) ? btdevice->idVendor : 0; }
uint16_t idProduct() { return (btdevice != nullptr) ? btdevice->idProduct : 0; }
const uint8_t *manufacturer()
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]]; }
const uint8_t *product()
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]]; }
const uint8_t *serialNumber()
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]]; }

private:
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class) {return false;}
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length) {return false;}
virtual void release_bluetooth() {};
void add_to_list();
BTHIDInput *next;
friend class BluetoothController;
protected:
Device_t *btdevice = NULL;
};


/************************************************/
/* USB Device Drivers */
/************************************************/
@@ -666,7 +695,7 @@ private:

//--------------------------------------------------------------------------

class KeyboardController : public USBDriver , public USBHIDInput {
class KeyboardController : public USBDriver , public USBHIDInput, public BTHIDInput {
public:
typedef union {
struct {
@@ -684,7 +713,13 @@ public:
KeyboardController(USBHost *host) { init(); }

// Some methods are in both public classes so we need to figure out which one to use
operator bool() { return (device != nullptr); }
uint16_t idVendor();
uint16_t idProduct();

const uint8_t *manufacturer();
const uint8_t *product();
const uint8_t *serialNumber();
operator bool() { return ((device != nullptr) || (btdevice != nullptr)); }
// Main boot keyboard functions.
uint16_t getKey() { return keyCode; }
uint8_t getModifiers() { return modifiers; }
@@ -715,6 +750,12 @@ protected:
void new_data(const Transfer_t *transfer);
void init();

// Bluetooth data
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class);
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length);
virtual void release_bluetooth();


protected: // HID functions for extra keyboard data.
virtual hidclaim_t claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage);
virtual void hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax);
@@ -783,7 +824,7 @@ private:

//--------------------------------------------------------------------------

class JoystickController : public USBDriver, public USBHIDInput {
class JoystickController : public USBDriver, public USBHIDInput, public BTHIDInput {
public:
JoystickController(USBHost &host) { init(); }

@@ -824,6 +865,12 @@ protected:
virtual void hid_input_end();
virtual void disconnect_collection(Device_t *dev);
virtual bool hid_process_out_data(const Transfer_t *transfer);

// Bluetooth data
virtual bool claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class);
virtual bool process_bluetooth_HID_data(const uint8_t *data, uint16_t length);
virtual void release_bluetooth();

private:

// Class specific
@@ -1548,4 +1595,122 @@ private:

};

//--------------------------------------------------------------------------

class BluetoothController: public USBDriver {
public:
BluetoothController(USBHost &host, bool pair = false, const char *pin = "0000") : do_pair_device_(pair), pair_pincode_(pin)
{ init(); }

enum {MAX_ENDPOINTS=4, NUM_SERVICES=4, }; // Max number of Bluetooth services - if you need more than 4 simply increase this number
enum {BT_CLASS_DEVICE= 0x0804}; // Toy - Robot
static void driver_ready_for_bluetooth(BTHIDInput *driver);

protected:
virtual bool claim(Device_t *device, int type, const uint8_t *descriptors, uint32_t len);
virtual void control(const Transfer_t *transfer);
virtual void disconnect();
//virtual void timer_event(USBDriverTimer *whichTimer);

BTHIDInput * find_driver(uint32_t device_type);
private:
static void rx_callback(const Transfer_t *transfer);
static void rx2_callback(const Transfer_t *transfer);
static void tx_callback(const Transfer_t *transfer);
void rx_data(const Transfer_t *transfer);
void rx2_data(const Transfer_t *transfer);
void tx_data(const Transfer_t *transfer);

void init();

// HCI support functions...
void sendHCICommand(uint16_t hciCommand, uint16_t cParams, const uint8_t* data);
//void sendHCIReadLocalSupportedFeatures();
void inline sendHCI_INQUIRY();
void inline sendHCIInquiryCancel();
void inline sendHCICreateConnection();
void inline sendHCIAuthenticationRequested();
void inline sendHCIAcceptConnectionRequest();
void inline sendHCILinkKeyNegativeReply();
void inline sendHCIPinCodeReply();
void inline sendResetHCI();
void inline sendHDCWriteClassOfDev();
void inline sendHCIReadBDAddr();
void inline sendHCIReadLocalVersionInfo();
void inline sendHCIWriteScanEnable(uint8_t scan_op);

void inline sendHCIRemoteNameRequest();
void inline sendHCIRemoteVersionInfoRequest();
void handle_hci_command_complete();
void handle_hci_command_status();
void handle_hci_inquiry_result();
void handle_hci_inquiry_complete();
void handle_hci_incoming_connect();
void handle_hci_connection_complete();
void handle_hci_disconnect_complete();
void handle_hci_authentication_complete();
void handle_hci_remote_name_complete();
void handle_hci_remote_version_information_complete();
void handle_hci_pin_code_request();
void handle_hci_link_key_notification();
void handle_hci_link_key_request();
void queue_next_hci_command();

void sendl2cap_ConnectionResponse(uint16_t handle, uint8_t rxid, uint16_t dcid, uint16_t scid, uint8_t result);
void sendl2cap_ConnectionRequest(uint16_t handle, uint8_t rxid, uint16_t scid, uint16_t psm);
void sendl2cap_ConfigRequest(uint16_t handle, uint8_t rxid, uint16_t dcid);
void sendl2cap_ConfigResponse(uint16_t handle, uint8_t rxid, uint16_t scid);
void sendL2CapCommand(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow = 0x01, uint8_t channelHigh = 0x00);

void process_l2cap_connection_request(uint8_t *data);
void process_l2cap_connection_response(uint8_t *data);
void process_l2cap_config_request(uint8_t *data);
void process_l2cap_config_response(uint8_t *data);
void process_l2cap_command_reject(uint8_t *data);
void process_l2cap_disconnect_request(uint8_t *data);

void setHIDProtocol(uint8_t protocol);
void handleHIDTHDRData(uint8_t *buffer); // Pass the whole buffer...
static BTHIDInput *available_bthid_drivers_list;


setup_t setup;
Pipe_t mypipes[4] __attribute__ ((aligned(32)));
Transfer_t mytransfers[7] __attribute__ ((aligned(32)));
strbuf_t mystring_bufs[2]; // 2 string buffers - one for our device - one for remote device...
uint16_t pending_control_ = 0;
uint16_t pending_control_tx_ = 0;
uint16_t rx_size_ = 0;
uint16_t rx2_size_ = 0;
uint16_t tx_size_ = 0;
Pipe_t *rxpipe_;
Pipe_t *rx2pipe_;
Pipe_t *txpipe_;
uint8_t rxbuf_[256]; // used to receive data from RX, which may come with several packets...
uint8_t rx_packet_data_remaining=0; // how much data remaining
uint8_t rx2buf_[64]; // receive buffer from Bulk end point
uint8_t txbuf_[256]; // buffer to use to send commands to bluetooth
uint8_t hciVersion; // what version of HCI do we have?

bool do_pair_device_; // Should we do a pair for a new device?
const char *pair_pincode_; // What pin code to use for the pairing
uint8_t my_bdaddr[6]; // The bluetooth dongles Bluetooth address.
uint8_t features[8]; // remember our local features.
BTHIDInput * device_driver_ = nullptr;;
uint8_t device_bdaddr_[6];// remember devices address
uint8_t device_ps_repetion_mode_ ; // mode
uint8_t device_clock_offset_[2];
uint32_t device_class_; // class of device.
uint16_t device_connection_handle_; // handle to connection
uint16_t connection_rxid_ = 0;
uint16_t control_dcid_ = 0x70;
uint16_t interrupt_dcid_ = 0x71;
uint16_t interrupt_scid_;
uint16_t control_scid_;
uint8_t remote_ver_;
uint16_t remote_man_;
uint8_t remote_subv_;

};

#endif

+ 1278
- 0
bluetooth.cpp
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 4
- 2
examples/Mouse/Mouse.ino Voir le fichier

@@ -16,14 +16,16 @@ USBHIDParser hid4(myusb);
USBHIDParser hid5(myusb);
MouseController mouse1(myusb);
JoystickController joystick1(myusb);
//BluetoothController bluet(myusb, true, "0000"); // Version does pairing to device
BluetoothController bluet(myusb); // version assumes it already was paired
int user_axis[64];
uint32_t buttons_prev = 0;
RawHIDController rawhid1(myusb);
RawHIDController rawhid2(myusb, 0xffc90004);

USBDriver *drivers[] = {&hub1, &hub2,&keyboard1, &keyboard2, &joystick1, &hid1, &hid2, &hid3, &hid4, &hid5};
USBDriver *drivers[] = {&hub1, &hub2,&keyboard1, &keyboard2, &joystick1, &bluet, &hid1, &hid2, &hid3, &hid4, &hid5};
#define CNT_DEVICES (sizeof(drivers)/sizeof(drivers[0]))
const char * driver_names[CNT_DEVICES] = {"Hub1","Hub2", "KB1", "KB2", "JOY1D", "HID1", "HID2", "HID3", "HID4", "HID5"};
const char * driver_names[CNT_DEVICES] = {"Hub1","Hub2", "KB1", "KB2", "JOY1D", "Bluet", "HID1" , "HID2", "HID3", "HID4", "HID5"};
bool driver_active[CNT_DEVICES] = {false, false, false, false};

// Lets also look at HID Input devices

+ 34
- 0
joystick.cpp Voir le fichier

@@ -47,6 +47,7 @@ void JoystickController::init()
contribute_String_Buffers(mystring_bufs, sizeof(mystring_bufs)/sizeof(strbuf_t));
driver_ready_for_device(this);
USBHIDParser::driver_ready_for_hid_collection(this);
BluetoothController::driver_ready_for_bluetooth(this);
}

//-----------------------------------------------------------------------------
@@ -643,4 +644,37 @@ void JoystickController::disconnect()
// TODO: free resources
}

bool JoystickController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class)
{
if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && ((bluetooth_class & 0x3C) == 0x08)) {
Serial.printf("JoystickController::claim_bluetooth TRUE\n");
//btdevice = driver;
return true;
}
return false;
}


bool JoystickController::process_bluetooth_HID_data(const uint8_t *data, uint16_t length)
{
// Example data from PS4 controller
//01 7e 7f 82 84 08 00 00 00 00
// LX LY RX RY BT BT PS LT RT
Serial.printf("JoystickController::process_bluetooth_HID_data\n");
if (data[0] != 1) return false;
print(" Joystick Data: ");
print_hexbytes(data, length);
Serial.printf(" Joystick Data: ");
for (uint16_t i = 0; i < length; i++ ) {
Serial.printf("%02x ", data[i]);
}
Serial.printf("\n");
return true;
}

void JoystickController::release_bluetooth()
{
//btdevice = nullptr;

}


+ 94
- 2
keyboard.cpp Voir le fichier

@@ -92,6 +92,44 @@ keycode_numlock_t keycode_numlock[] = {
#define print USBHost::print_
#define println USBHost::println_


uint16_t KeyboardController::idVendor()
{
if (device != nullptr) return device->idVendor;
if (btdevice != nullptr) return btdevice->idVendor;
return 0;
}

uint16_t KeyboardController::idProduct()
{
if (device != nullptr) return device->idProduct;
if (btdevice != nullptr) return btdevice->idProduct;
return 0;
}

const uint8_t *KeyboardController::manufacturer()
{
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
if ((btdevice != nullptr) && (btdevice->strbuf != nullptr)) return &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
return nullptr;
}

const uint8_t *KeyboardController::product()
{
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
if ((btdevice != nullptr) && (btdevice->strbuf != nullptr)) return &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
return nullptr;
}

const uint8_t *KeyboardController::serialNumber()
{
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
if ((btdevice != nullptr) && (btdevice->strbuf != nullptr)) return &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
return nullptr;
}



void KeyboardController::init()
{
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
@@ -99,6 +137,7 @@ void KeyboardController::init()
contribute_String_Buffers(mystring_bufs, sizeof(mystring_bufs)/sizeof(strbuf_t));
driver_ready_for_device(this);
USBHIDParser::driver_ready_for_hid_collection(this);
BluetoothController::driver_ready_for_bluetooth(this);
}

bool KeyboardController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
@@ -334,8 +373,13 @@ void KeyboardController::LEDS(uint8_t leds) {

void KeyboardController::updateLEDS() {
// Now lets tell keyboard new state.
mk_setup(setup, 0x21, 9, 0x200, 0, sizeof(leds_.byte)); // hopefully this sets leds
queue_Control_Transfer(device, &setup, &leds_.byte, this);
if (device != nullptr) {
// Only do it this way if we are a standard USB device
mk_setup(setup, 0x21, 9, 0x200, 0, sizeof(leds_.byte)); // hopefully this sets leds
queue_Control_Transfer(device, &setup, &leds_.byte, this);
} else {
// Bluetooth, need to setup back channel to Bluetooth controller.
}
}

//=============================================================================
@@ -437,3 +481,51 @@ void KeyboardController::hid_input_end()
hid_input_begin_ = false;
}
}

bool KeyboardController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class)
{
Serial.printf("Keyboard Controller::claim_bluetooth - Class %x\n", bluetooth_class);
if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && (bluetooth_class & 0x40)) {
Serial.printf("KeyboardController::claim_bluetooth TRUE\n");
//btdevice = driver;
return true;
}
return false;
}

bool KeyboardController::process_bluetooth_HID_data(const uint8_t *data, uint16_t length)
{
// Example DATA from bluetooth keyboard:
// 0 1 2 3 4 5 6 7 8 910 1 2 3 4 5 6 7
// LEN D
//BT rx2_data(18): 48 20 e 0 a 0 70 0 a1 1 2 0 0 0 0 0 0 0
//BT rx2_data(18): 48 20 e 0 a 0 70 0 a1 1 2 0 4 0 0 0 0 0
//BT rx2_data(18): 48 20 e 0 a 0 70 0 a1 1 2 0 0 0 0 0 0 0
// So Len=9 passed in data starting at report ID=1...
Serial.printf("KeyboardController::process_bluetooth_HID_data\n");
if (data[0] != 1) return false;
print(" KB Data: ");
print_hexbytes(data, length);
for (int i=2; i < length; i++) {
uint32_t key = prev_report[i];
if (key >= 4 && !contains(key, report)) {
key_release(prev_report[0], key);
}
}
for (int i=2; i < 8; i++) {
uint32_t key = data[i];
if (key >= 4 && !contains(key, prev_report)) {
key_press(data[1], key);
}
}
// Save away the data.. But shift down one byte... Don't need the report number
memcpy(prev_report, &data[1], 8);
return true;
}

void KeyboardController::release_bluetooth()
{
//btdevice = nullptr;

}


Chargement…
Annuler
Enregistrer