mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Some minor changes
This commit is contained in:
parent
a70deaf5cc
commit
1ff0135b31
6 changed files with 111 additions and 95 deletions
10
BTD.cpp
10
BTD.cpp
|
@ -295,7 +295,7 @@ void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
|
||||||
uint8_t BTD::Release() {
|
uint8_t BTD::Release() {
|
||||||
for (uint8_t i=0; i<BTD_NUMDEVICES; i++)
|
for (uint8_t i=0; i<BTD_NUMDEVICES; i++)
|
||||||
if (btService[i])
|
if (btService[i])
|
||||||
btService[i]->Release(); // Reset both the L2CAP Channel and the HCI Connection
|
btService[i]->Reset(); // Reset both the L2CAP Channel and the HCI Connection
|
||||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0;
|
||||||
bPollEnable = false;
|
bPollEnable = false;
|
||||||
|
@ -565,8 +565,11 @@ void BTD::HCI_task() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_DONE_STATE:
|
case HCI_DONE_STATE:
|
||||||
|
hci_counter++;
|
||||||
|
if (hci_counter > 100) { // Wait until we have looped 100 times to make sure that the L2CAP connection has been started
|
||||||
hci_state = HCI_SCANNING_STATE;
|
hci_state = HCI_SCANNING_STATE;
|
||||||
connectionClaimed = false;
|
l2capConnectionClaimed = false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_DISCONNECT_STATE:
|
case HCI_DISCONNECT_STATE:
|
||||||
|
@ -605,7 +608,7 @@ void BTD::ACL_event_task() {
|
||||||
}
|
}
|
||||||
for (uint8_t i=0; i<BTD_NUMDEVICES; i++)
|
for (uint8_t i=0; i<BTD_NUMDEVICES; i++)
|
||||||
if (btService[i])
|
if (btService[i])
|
||||||
btService[i]->Poll();
|
btService[i]->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
@ -792,6 +795,7 @@ void BTD::L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t
|
||||||
|
|
||||||
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
|
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
|
||||||
if(rcode) {
|
if(rcode) {
|
||||||
|
delay(100); // This small delay prevents it from overflowing if it fails
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Notify(PSTR("\r\nError sending L2CAP message: 0x"));
|
Notify(PSTR("\r\nError sending L2CAP message: 0x"));
|
||||||
PrintHex<uint8_t>(rcode);
|
PrintHex<uint8_t>(rcode);
|
||||||
|
|
8
BTD.h
8
BTD.h
|
@ -115,8 +115,8 @@
|
||||||
class BluetoothService { // All services should include this class
|
class BluetoothService { // All services should include this class
|
||||||
public:
|
public:
|
||||||
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
||||||
virtual void Poll(); // Used to run the different state machines
|
virtual void Run(); // Used to run the different state machines
|
||||||
virtual void Release(); // Used to reset the services
|
virtual void Reset(); // Used to reset the services
|
||||||
virtual void disconnect(); // Used to disconnect both the L2CAP Channel and the HCI Connection
|
virtual void disconnect(); // Used to disconnect both the L2CAP Channel and the HCI Connection
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -152,8 +152,8 @@ public:
|
||||||
return 1; // ErrorregisterServiceClass
|
return 1; // ErrorregisterServiceClass
|
||||||
};
|
};
|
||||||
|
|
||||||
void claimConnection() { connectionClaimed = true; }; // This is used by the service to know when to store the device information
|
void claimConnection() { l2capConnectionClaimed = true; }; // This is used by the service to know when to store the device information
|
||||||
bool connectionClaimed;
|
bool l2capConnectionClaimed;
|
||||||
|
|
||||||
const char* btdName; // These are set by the SPP library
|
const char* btdName; // These are set by the SPP library
|
||||||
const char* btdPin;
|
const char* btdPin;
|
||||||
|
|
69
PS3BT.cpp
69
PS3BT.cpp
|
@ -58,7 +58,7 @@ pBtd(p) // pointer to USB class instance - mandatory
|
||||||
interrupt_dcid[0] = 0x41;//0x0041
|
interrupt_dcid[0] = 0x41;//0x0041
|
||||||
interrupt_dcid[1] = 0x00;
|
interrupt_dcid[1] = 0x00;
|
||||||
|
|
||||||
Release();
|
Reset();
|
||||||
}
|
}
|
||||||
bool PS3BT::getButton(Button b) {
|
bool PS3BT::getButton(Button b) {
|
||||||
if (l2capinbuf == NULL)
|
if (l2capinbuf == NULL)
|
||||||
|
@ -209,7 +209,7 @@ String PS3BT::getStatusString() {
|
||||||
return statusOutput;
|
return statusOutput;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void PS3BT::Release() {
|
void PS3BT::Reset() {
|
||||||
PS3Connected = false;
|
PS3Connected = false;
|
||||||
PS3MoveConnected = false;
|
PS3MoveConnected = false;
|
||||||
PS3NavigationConnected = false;
|
PS3NavigationConnected = false;
|
||||||
|
@ -233,11 +233,9 @@ void PS3BT::disconnect() { //Use this void to disconnect any of the controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
void PS3BT::ACLData(uint8_t* ACLData) {
|
void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
for(uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
|
if(!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected) {
|
||||||
l2capinbuf[i] = ACLData[i];
|
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
if(((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) || ((ACLData[12] | (ACLData[13] << 8)) == HID_INTR_PSM)) {
|
||||||
if(((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) || ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM)) {
|
|
||||||
if(!pBtd->connectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected) {
|
|
||||||
pBtd->claimConnection(); // Claim that the incoming connection belongs to this service
|
pBtd->claimConnection(); // Claim that the incoming connection belongs to this service
|
||||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||||
for(uint8_t i = 0; i < 30; i++)
|
for(uint8_t i = 0; i < 30; i++)
|
||||||
|
@ -252,7 +250,9 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok
|
if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok
|
||||||
|
for(uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
|
||||||
|
l2capinbuf[i] = ACLData[i];
|
||||||
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
|
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -401,9 +401,10 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
L2CAP_task();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void PS3BT::Poll() {
|
void PS3BT::L2CAP_task() {
|
||||||
switch (l2cap_state) {
|
switch (l2cap_state) {
|
||||||
case L2CAP_EV_WAIT:
|
case L2CAP_EV_WAIT:
|
||||||
if (l2cap_connection_request_control_flag) {
|
if (l2cap_connection_request_control_flag) {
|
||||||
|
@ -478,6 +479,34 @@ void PS3BT::Poll() {
|
||||||
timer = millis();
|
timer = millis();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* These states are handled in Run() */
|
||||||
|
|
||||||
|
case L2CAP_EV_INTERRUPT_DISCONNECT:
|
||||||
|
if (l2cap_disconnect_response_interrupt_flag) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
Notify(PSTR("\r\nDisconnected Interrupt Channel"));
|
||||||
|
#endif
|
||||||
|
identifier++;
|
||||||
|
pBtd->l2cap_disconnection_request(hci_handle, identifier, control_scid, control_dcid);
|
||||||
|
l2cap_event_flag = 0; // Reset flags
|
||||||
|
l2cap_state = L2CAP_EV_CONTROL_DISCONNECT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L2CAP_EV_CONTROL_DISCONNECT:
|
||||||
|
if (l2cap_disconnect_response_control_flag) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
Notify(PSTR("\r\nDisconnected Control Channel"));
|
||||||
|
#endif
|
||||||
|
pBtd->hci_disconnect(hci_handle);
|
||||||
|
l2cap_state = L2CAP_EV_WAIT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void PS3BT::Run() {
|
||||||
|
switch (l2cap_state) {
|
||||||
case L2CAP_EV_HID_ENABLE_SIXAXIS:
|
case L2CAP_EV_HID_ENABLE_SIXAXIS:
|
||||||
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
if(millis() - timer > 1000) { // loop 1 second before sending the command
|
||||||
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed
|
for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed
|
||||||
|
@ -527,28 +556,6 @@ void PS3BT::Poll() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case L2CAP_EV_INTERRUPT_DISCONNECT:
|
|
||||||
if (l2cap_disconnect_response_interrupt_flag) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
Notify(PSTR("\r\nDisconnected Interrupt Channel"));
|
|
||||||
#endif
|
|
||||||
identifier++;
|
|
||||||
pBtd->l2cap_disconnection_request(hci_handle, identifier, control_scid, control_dcid);
|
|
||||||
l2cap_event_flag = 0; // Reset flags
|
|
||||||
l2cap_state = L2CAP_EV_CONTROL_DISCONNECT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L2CAP_EV_CONTROL_DISCONNECT:
|
|
||||||
if (l2cap_disconnect_response_control_flag) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
Notify(PSTR("\r\nDisconnected Control Channel"));
|
|
||||||
#endif
|
|
||||||
pBtd->hci_disconnect(hci_handle);
|
|
||||||
l2cap_state = L2CAP_EV_WAIT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
PS3BT.h
6
PS3BT.h
|
@ -219,8 +219,8 @@ public:
|
||||||
|
|
||||||
// BluetoothService implementation
|
// BluetoothService implementation
|
||||||
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
||||||
virtual void Poll(); // Used to run the state maschine
|
virtual void Run(); // Used to run part of the state maschine
|
||||||
virtual void Release(); // Use this to reset the service
|
virtual void Reset(); // Use this to reset the service
|
||||||
virtual void disconnect(); // Use this void to disconnect any of the controllers
|
virtual void disconnect(); // Use this void to disconnect any of the controllers
|
||||||
|
|
||||||
/* PS3 Controller Commands */
|
/* PS3 Controller Commands */
|
||||||
|
@ -258,6 +258,8 @@ private:
|
||||||
/* mandatory members */
|
/* mandatory members */
|
||||||
BTD *pBtd;
|
BTD *pBtd;
|
||||||
|
|
||||||
|
void L2CAP_task(); // L2CAP state machine
|
||||||
|
|
||||||
/* Variables filled from HCI event management */
|
/* Variables filled from HCI event management */
|
||||||
int16_t hci_handle;
|
int16_t hci_handle;
|
||||||
uint8_t remote_name[30]; // first 30 chars of remote name
|
uint8_t remote_name[30]; // first 30 chars of remote name
|
||||||
|
|
28
SPP.cpp
28
SPP.cpp
|
@ -50,17 +50,16 @@ pBtd(p) // Pointer to BTD class instance - mandatory
|
||||||
|
|
||||||
pBtd->btdName = name;
|
pBtd->btdName = name;
|
||||||
pBtd->btdPin = pin;
|
pBtd->btdPin = pin;
|
||||||
l2cap_sdp_state = L2CAP_SDP_WAIT;
|
|
||||||
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
|
|
||||||
l2cap_event_flag = 0;
|
|
||||||
|
|
||||||
/* Set device cid for the SDP and RFCOMM channelse */
|
/* Set device cid for the SDP and RFCOMM channelse */
|
||||||
sdp_dcid[0] = 0x50; // 0x0050
|
sdp_dcid[0] = 0x50; // 0x0050
|
||||||
sdp_dcid[1] = 0x00;
|
sdp_dcid[1] = 0x00;
|
||||||
rfcomm_dcid[0] = 0x51; // 0x0051
|
rfcomm_dcid[0] = 0x51; // 0x0051
|
||||||
rfcomm_dcid[1] = 0x00;
|
rfcomm_dcid[1] = 0x00;
|
||||||
|
|
||||||
|
Reset();
|
||||||
}
|
}
|
||||||
void SPP::Release() {
|
void SPP::Reset() {
|
||||||
connected = false;
|
connected = false;
|
||||||
RFCOMMConnected = false;
|
RFCOMMConnected = false;
|
||||||
SDPConnected = false;
|
SDPConnected = false;
|
||||||
|
@ -78,16 +77,18 @@ void SPP::disconnect(){
|
||||||
l2cap_event_flag = 0; // Reset flags
|
l2cap_event_flag = 0; // Reset flags
|
||||||
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
|
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
|
||||||
}
|
}
|
||||||
void SPP::ACLData(uint8_t* l2capinbuf) {
|
void SPP::ACLData(uint8_t* ACLData) {
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
if(!pBtd->l2capConnectionClaimed && !connected && !RFCOMMConnected && !SDPConnected) {
|
||||||
if(((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM) || ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM)) {
|
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||||
if(!pBtd->connectionClaimed && !connected && !RFCOMMConnected && !SDPConnected) {
|
if(((ACLData[12] | (ACLData[13] << 8)) == SDP_PSM) || ((ACLData[12] | (ACLData[13] << 8)) == RFCOMM_PSM)) {
|
||||||
pBtd->claimConnection(); // Claim that the incoming connection belongs to this service
|
pBtd->claimConnection(); // Claim that the incoming connection belongs to this service
|
||||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000))) { // acl_handle_ok
|
if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { // acl_handle_ok
|
||||||
|
for(uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
|
||||||
|
l2capinbuf[i] = ACLData[i];
|
||||||
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
|
if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U
|
||||||
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -362,9 +363,11 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||||
PrintHex<uint8_t>(l2capinbuf[6]);
|
PrintHex<uint8_t>(l2capinbuf[6]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
SDP_task();
|
||||||
|
RFCOMM_task();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SPP::Poll() {
|
void SPP::Run() {
|
||||||
if(waitForLastCommand && (millis() - timer) > 100) { // We will only wait 100ms and see if the UIH Remote Port Negotiation Command is send, as some deviced don't send it
|
if(waitForLastCommand && (millis() - timer) > 100) { // We will only wait 100ms and see if the UIH Remote Port Negotiation Command is send, as some deviced don't send it
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"));
|
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"));
|
||||||
|
@ -373,8 +376,6 @@ void SPP::Poll() {
|
||||||
waitForLastCommand = false;
|
waitForLastCommand = false;
|
||||||
connected = true; // The RFCOMM channel is now established
|
connected = true; // The RFCOMM channel is now established
|
||||||
}
|
}
|
||||||
SDP_task();
|
|
||||||
RFCOMM_task();
|
|
||||||
}
|
}
|
||||||
void SPP::SDP_task() {
|
void SPP::SDP_task() {
|
||||||
switch (l2cap_sdp_state)
|
switch (l2cap_sdp_state)
|
||||||
|
@ -773,7 +774,8 @@ void SPP::println(const __FlashStringHelper *ifsh) {
|
||||||
print(buf,size+2);
|
print(buf,size+2);
|
||||||
}
|
}
|
||||||
void SPP::println(void) {
|
void SPP::println(void) {
|
||||||
print("\r\n");
|
uint8_t buf[2] = {'\r','\n'};
|
||||||
|
print(buf,2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* These must be used to print numbers */
|
/* These must be used to print numbers */
|
||||||
|
|
5
SPP.h
5
SPP.h
|
@ -99,8 +99,8 @@ public:
|
||||||
|
|
||||||
// BluetoothService implementation
|
// BluetoothService implementation
|
||||||
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
||||||
virtual void Poll(); // Used to run SDP_task() and RFCOMM_task()
|
virtual void Run(); // Used to establish the connection automatically
|
||||||
virtual void Release(); // Use this to reset the service
|
virtual void Reset(); // Use this to reset the service
|
||||||
virtual void disconnect(); // Used this void to disconnect the virtual serial port
|
virtual void disconnect(); // Used this void to disconnect the virtual serial port
|
||||||
|
|
||||||
bool connected;// Variable used to indicate if the connection is established
|
bool connected;// Variable used to indicate if the connection is established
|
||||||
|
@ -141,6 +141,7 @@ private:
|
||||||
uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events
|
uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events
|
||||||
|
|
||||||
uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
|
uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
|
||||||
|
uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap in data
|
||||||
uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
|
uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
|
||||||
|
|
||||||
/* L2CAP Channels */
|
/* L2CAP Channels */
|
||||||
|
|
Loading…
Reference in a new issue