Some minor changes

This commit is contained in:
Kristian Lauszus 2012-08-08 05:40:53 +02:00
parent a70deaf5cc
commit 1ff0135b31
6 changed files with 111 additions and 95 deletions

10
BTD.cpp
View file

@ -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
View file

@ -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;

View file

@ -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;
} }
} }

View file

@ -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
View file

@ -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
View file

@ -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 */