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
12
BTD.cpp
12
BTD.cpp
|
@ -295,7 +295,7 @@ void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
|
|||
uint8_t BTD::Release() {
|
||||
for (uint8_t i=0; i<BTD_NUMDEVICES; 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);
|
||||
bAddress = 0;
|
||||
bPollEnable = false;
|
||||
|
@ -565,8 +565,11 @@ void BTD::HCI_task() {
|
|||
break;
|
||||
|
||||
case HCI_DONE_STATE:
|
||||
hci_state = HCI_SCANNING_STATE;
|
||||
connectionClaimed = false;
|
||||
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;
|
||||
l2capConnectionClaimed = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_DISCONNECT_STATE:
|
||||
|
@ -605,7 +608,7 @@ void BTD::ACL_event_task() {
|
|||
}
|
||||
for (uint8_t i=0; i<BTD_NUMDEVICES; 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);
|
||||
if(rcode) {
|
||||
delay(100); // This small delay prevents it from overflowing if it fails
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nError sending L2CAP message: 0x"));
|
||||
PrintHex<uint8_t>(rcode);
|
||||
|
|
8
BTD.h
8
BTD.h
|
@ -115,8 +115,8 @@
|
|||
class BluetoothService { // All services should include this class
|
||||
public:
|
||||
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 Release(); // Used to reset the services
|
||||
virtual void Run(); // Used to run the different state machines
|
||||
virtual void Reset(); // Used to reset the services
|
||||
virtual void disconnect(); // Used to disconnect both the L2CAP Channel and the HCI Connection
|
||||
};
|
||||
|
||||
|
@ -152,8 +152,8 @@ public:
|
|||
return 1; // ErrorregisterServiceClass
|
||||
};
|
||||
|
||||
void claimConnection() { connectionClaimed = true; }; // This is used by the service to know when to store the device information
|
||||
bool connectionClaimed;
|
||||
void claimConnection() { l2capConnectionClaimed = true; }; // This is used by the service to know when to store the device information
|
||||
bool l2capConnectionClaimed;
|
||||
|
||||
const char* btdName; // These are set by the SPP library
|
||||
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[1] = 0x00;
|
||||
|
||||
Release();
|
||||
Reset();
|
||||
}
|
||||
bool PS3BT::getButton(Button b) {
|
||||
if (l2capinbuf == NULL)
|
||||
|
@ -209,7 +209,7 @@ String PS3BT::getStatusString() {
|
|||
return statusOutput;
|
||||
}
|
||||
}
|
||||
void PS3BT::Release() {
|
||||
void PS3BT::Reset() {
|
||||
PS3Connected = false;
|
||||
PS3MoveConnected = 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) {
|
||||
for(uint8_t i = 0; i < BULK_MAXPKTSIZE; i++)
|
||||
l2capinbuf[i] = ACLData[i];
|
||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||
if(((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) || ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM)) {
|
||||
if(!pBtd->connectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected) {
|
||||
if(!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected) {
|
||||
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||
if(((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) || ((ACLData[12] | (ACLData[13] << 8)) == HID_INTR_PSM)) {
|
||||
pBtd->claimConnection(); // Claim that the incoming connection belongs to this service
|
||||
hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
|
||||
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[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||
#ifdef DEBUG
|
||||
|
@ -401,9 +401,10 @@ void PS3BT::ACLData(uint8_t* ACLData) {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
L2CAP_task();
|
||||
}
|
||||
}
|
||||
void PS3BT::Poll() {
|
||||
void PS3BT::L2CAP_task() {
|
||||
switch (l2cap_state) {
|
||||
case L2CAP_EV_WAIT:
|
||||
if (l2cap_connection_request_control_flag) {
|
||||
|
@ -478,6 +479,34 @@ void PS3BT::Poll() {
|
|||
timer = millis();
|
||||
}
|
||||
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:
|
||||
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
|
||||
|
@ -527,28 +556,6 @@ void PS3BT::Poll() {
|
|||
}
|
||||
}
|
||||
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
|
||||
virtual void ACLData(uint8_t* ACLData); // Used to pass acldata to the services
|
||||
virtual void Poll(); // Used to run the state maschine
|
||||
virtual void Release(); // Use this to reset the service
|
||||
virtual void Run(); // Used to run part of the state maschine
|
||||
virtual void Reset(); // Use this to reset the service
|
||||
virtual void disconnect(); // Use this void to disconnect any of the controllers
|
||||
|
||||
/* PS3 Controller Commands */
|
||||
|
@ -258,6 +258,8 @@ private:
|
|||
/* mandatory members */
|
||||
BTD *pBtd;
|
||||
|
||||
void L2CAP_task(); // L2CAP state machine
|
||||
|
||||
/* Variables filled from HCI event management */
|
||||
int16_t hci_handle;
|
||||
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->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 */
|
||||
sdp_dcid[0] = 0x50; // 0x0050
|
||||
sdp_dcid[1] = 0x00;
|
||||
rfcomm_dcid[0] = 0x51; // 0x0051
|
||||
rfcomm_dcid[1] = 0x00;
|
||||
|
||||
Reset();
|
||||
}
|
||||
void SPP::Release() {
|
||||
void SPP::Reset() {
|
||||
connected = false;
|
||||
RFCOMMConnected = false;
|
||||
SDPConnected = false;
|
||||
|
@ -78,16 +77,18 @@ void SPP::disconnect(){
|
|||
l2cap_event_flag = 0; // Reset flags
|
||||
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
|
||||
}
|
||||
void SPP::ACLData(uint8_t* l2capinbuf) {
|
||||
if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||
if(((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM) || ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM)) {
|
||||
if(!pBtd->connectionClaimed && !connected && !RFCOMMConnected && !SDPConnected) {
|
||||
void SPP::ACLData(uint8_t* ACLData) {
|
||||
if(!pBtd->l2capConnectionClaimed && !connected && !RFCOMMConnected && !SDPConnected) {
|
||||
if (ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
|
||||
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
|
||||
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[8] == L2CAP_CMD_COMMAND_REJECT) {
|
||||
#ifdef DEBUG
|
||||
|
@ -362,9 +363,11 @@ void SPP::ACLData(uint8_t* l2capinbuf) {
|
|||
PrintHex<uint8_t>(l2capinbuf[6]);
|
||||
#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
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"));
|
||||
|
@ -373,8 +376,6 @@ void SPP::Poll() {
|
|||
waitForLastCommand = false;
|
||||
connected = true; // The RFCOMM channel is now established
|
||||
}
|
||||
SDP_task();
|
||||
RFCOMM_task();
|
||||
}
|
||||
void SPP::SDP_task() {
|
||||
switch (l2cap_sdp_state)
|
||||
|
@ -773,7 +774,8 @@ void SPP::println(const __FlashStringHelper *ifsh) {
|
|||
print(buf,size+2);
|
||||
}
|
||||
void SPP::println(void) {
|
||||
print("\r\n");
|
||||
uint8_t buf[2] = {'\r','\n'};
|
||||
print(buf,2);
|
||||
}
|
||||
|
||||
/* These must be used to print numbers */
|
||||
|
|
5
SPP.h
5
SPP.h
|
@ -99,8 +99,8 @@ public:
|
|||
|
||||
// BluetoothService implementation
|
||||
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 Release(); // Use this to reset the service
|
||||
virtual void Run(); // Used to establish the connection automatically
|
||||
virtual void Reset(); // Use this to reset the service
|
||||
virtual void disconnect(); // Used this void to disconnect the virtual serial port
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
/* L2CAP Channels */
|
||||
|
|
Loading…
Reference in a new issue