mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Merge branch 'dev' of github.com:felis/USB_Host_Shield_2.0 into dev
This commit is contained in:
commit
becfcd0270
2 changed files with 62 additions and 49 deletions
96
RFCOMM.cpp
96
RFCOMM.cpp
|
@ -18,7 +18,7 @@
|
|||
#include "RFCOMM.h"
|
||||
#define DEBUG // Uncomment to print data for debugging
|
||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
||||
//#define PRINTREPORT // Uncomment to print the report sent to the Arduino
|
||||
|
||||
const uint8_t RFCOMM::BTD_EVENT_PIPE = 1;
|
||||
const uint8_t RFCOMM::BTD_DATAIN_PIPE = 2;
|
||||
|
@ -27,7 +27,7 @@ const uint8_t RFCOMM::BTD_DATAOUT_PIPE = 3;
|
|||
/*
|
||||
* CRC (reversed crc) lookup table as calculated by the table generator in ETSI TS 101 369 V6.3.0.
|
||||
*/
|
||||
const uint8_t rfcomm_crc_table[256] = { /* reversed, 8-bit, poly=0x07 */
|
||||
const uint8_t rfcomm_crc_table[256] PROGMEM = { /* reversed, 8-bit, poly=0x07 */
|
||||
0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
|
||||
0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
|
||||
0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
|
||||
|
@ -46,7 +46,7 @@ const uint8_t rfcomm_crc_table[256] = { /* reversed, 8-bit, poly=0x07 */
|
|||
0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
|
||||
};
|
||||
|
||||
RFCOMM::RFCOMM(USB *p, const char* name, const char* key):
|
||||
RFCOMM::RFCOMM(USB *p, const char* name, const char* pin):
|
||||
pUsb(p), // pointer to USB class instance - mandatory
|
||||
bAddress(0), // device address - mandatory
|
||||
bNumEP(1), // if config descriptor needs to be parsed
|
||||
|
@ -65,7 +65,7 @@ bPollEnable(false) // don't start polling before dongle is connected
|
|||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||
|
||||
btdName = name;
|
||||
btdKey = key;
|
||||
btdPin = pin;
|
||||
}
|
||||
|
||||
uint8_t RFCOMM::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||
|
@ -324,7 +324,7 @@ void RFCOMM::disconnect() { // Use this void to disconnect the RFCOMM Channel
|
|||
connected = false;
|
||||
// First the HID interrupt channel has to be disconencted, then the HID control channel and finally the HCI connection
|
||||
if(RFCOMMConnected)
|
||||
l2cap_disconnection_request(0x0A, rfcomm_dcid, rfcomm_scid);
|
||||
l2cap_disconnection_request(0x0A, rfcomm_dcid, rfcomm_scid);
|
||||
if(SDPConnected)
|
||||
l2cap_disconnection_request(0x0B, sdp_dcid, sdp_scid);
|
||||
l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
|
||||
|
@ -355,9 +355,9 @@ void RFCOMM::HCI_event_task() {
|
|||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nHCI Command Failed: "));
|
||||
PrintHex<uint8_t>(hcibuf[2]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
PrintHex<uint8_t>(hcibuf[4]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
PrintHex<uint8_t>(hcibuf[5]);
|
||||
#endif
|
||||
}
|
||||
|
@ -397,10 +397,10 @@ void RFCOMM::HCI_event_task() {
|
|||
|
||||
case EV_PIN_CODE_REQUEST:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nBluetooth key is set too: "));
|
||||
Serial.print(btdKey);
|
||||
Notify(PSTR("\r\nBluetooth pin is set too: "));
|
||||
Serial.print(btdPin);
|
||||
#endif
|
||||
hci_pin_code_request_reply(btdKey);
|
||||
hci_pin_code_request_reply(btdPin);
|
||||
break;
|
||||
|
||||
case EV_LINK_KEY_REQUEST:
|
||||
|
@ -484,7 +484,7 @@ void RFCOMM::HCI_task() {
|
|||
if (hci_read_bdaddr_complete)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nLocal Bluetooth Address: "));
|
||||
Notify(PSTR("\r\nLocal Bluetooth Address: "));
|
||||
for(int8_t i = 5; i > 0;i--)
|
||||
{
|
||||
PrintHex<uint8_t>(my_bdaddr[i]);
|
||||
|
@ -625,15 +625,15 @@ void RFCOMM::ACL_event_task()
|
|||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "));
|
||||
PrintHex<uint8_t>(l2capinbuf[13]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
PrintHex<uint8_t>(l2capinbuf[12]);
|
||||
Serial.print(" Data: ");
|
||||
Notify(PSTR(" Data: "));
|
||||
PrintHex<uint8_t>(l2capinbuf[17]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
PrintHex<uint8_t>(l2capinbuf[16]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
PrintHex<uint8_t>(l2capinbuf[15]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
PrintHex<uint8_t>(l2capinbuf[14]);
|
||||
#endif
|
||||
}
|
||||
|
@ -641,13 +641,13 @@ void RFCOMM::ACL_event_task()
|
|||
#ifdef EXTRADEBUG
|
||||
Notify(PSTR("\r\nL2CAP Connection Request - PSM: "));
|
||||
PrintHex<uint8_t>(l2capinbuf[13]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
PrintHex<uint8_t>(l2capinbuf[12]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
|
||||
Notify(PSTR(" SCID: "));
|
||||
PrintHex<uint8_t>(l2capinbuf[15]);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
PrintHex<uint8_t>(l2capinbuf[14]);
|
||||
|
||||
Notify(PSTR(" Identifier: "));
|
||||
|
@ -770,15 +770,15 @@ void RFCOMM::ACL_event_task()
|
|||
if(rfcommChannel>>3 != 0x00)
|
||||
rfcommChannelPermanent = rfcommChannel;
|
||||
#ifdef EXTRADEBUG
|
||||
Serial.print("\r\nRFCOMM Channel: ");
|
||||
Notify(PSTR("\r\nRFCOMM Channel: "));
|
||||
Serial.print(rfcommChannel>>3,HEX);
|
||||
Serial.print(" Direction: ");
|
||||
Notify(PSTR(" Direction: "));
|
||||
Serial.print(rfcommDirection>>2,HEX);
|
||||
Serial.print(" CommandResponse: ");
|
||||
Notify(PSTR(" CommandResponse: "));
|
||||
Serial.print(rfcommCommandResponse>>1,HEX);
|
||||
Serial.print(" ChannelType: ");
|
||||
Notify(PSTR(" ChannelType: "));
|
||||
Serial.print(rfcommChannelType,HEX);
|
||||
Serial.print(" PF_BIT: ");
|
||||
Notify(PSTR(" PF_BIT: "));
|
||||
Serial.print(rfcommPfBit,HEX);
|
||||
#endif
|
||||
if(connected) {
|
||||
|
@ -830,7 +830,9 @@ void RFCOMM::ACL_event_task()
|
|||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nUIH Command with credit"));
|
||||
#endif
|
||||
sendRfcommCredit(rfcommChannelPermanent,rfcommDirection,0,RFCOMM_UIH,0x10,0xFF); // 255 credit
|
||||
sendRfcommCredit(rfcommChannelPermanent,rfcommDirection,0,RFCOMM_UIH,0x10,0xFF); // 255 credit
|
||||
timer = millis();
|
||||
waitForLastCommand = true;
|
||||
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nUIH Remote Port Negotiation Command"));
|
||||
|
@ -849,20 +851,15 @@ void RFCOMM::ACL_event_task()
|
|||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nRFCOMM Connection is now established\r\n"));
|
||||
#endif
|
||||
waitForLastCommand = false;
|
||||
connected = true; // The RFCOMM channel is now established
|
||||
} else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] != BT_RFCOMM_RPN_CMD) { // Some deviced don't send the UIH Remote Port Negotiation Command
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nRFCOMM Connection is now established\r\n"));
|
||||
#endif
|
||||
readReport();
|
||||
#ifdef PRINTREPORT
|
||||
printReport(); //Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth
|
||||
#endif
|
||||
connected = true; // The RFCOMM channel is now established
|
||||
} else if (rfcommChannelType == RFCOMM_DISC) {
|
||||
}
|
||||
|
||||
else if (rfcommChannelType == RFCOMM_DISC) {
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nReceived Disconnect RFCOMM Command"));
|
||||
#endif
|
||||
l2cap_disconnection_request(0x0A, rfcomm_dcid, rfcomm_scid);
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nUnsupported RFCOMM - ChannelType: "));
|
||||
|
@ -945,6 +942,16 @@ void RFCOMM::SDP_task() {
|
|||
}
|
||||
void RFCOMM::RFCOMM_task()
|
||||
{
|
||||
if(!connected) {
|
||||
if((millis() - timer) > 100 && waitForLastCommand) { // 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\r\n"));
|
||||
#endif
|
||||
waitForLastCommand = false;
|
||||
connected = true; // The RFCOMM channel is now established
|
||||
|
||||
}
|
||||
}
|
||||
switch (l2cap_rfcomm_state)
|
||||
{
|
||||
case L2CAP_RFCOMM_WAIT:
|
||||
|
@ -989,7 +996,7 @@ void RFCOMM::RFCOMM_task()
|
|||
#endif
|
||||
l2cap_disconnection_response(identifier,rfcomm_dcid,rfcomm_scid);
|
||||
l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1119,7 +1126,7 @@ void RFCOMM::hci_pin_code_request_reply(const char* key) {
|
|||
HCI_Command(hcibuf, 26);
|
||||
}
|
||||
void RFCOMM::hci_link_key_request_negative_reply() {
|
||||
hcibuf[0] = 0x0C; // HCI OCF = 9
|
||||
hcibuf[0] = 0x0C; // HCI OCF = 0C
|
||||
hcibuf[1] = 0x01 << 2; // HCI OGF = 1
|
||||
hcibuf[2] = 0x06; // parameter length 7
|
||||
hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr
|
||||
|
@ -1466,10 +1473,10 @@ void RFCOMM::sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t
|
|||
l2capoutbuf[i+3] = data[i];
|
||||
l2capoutbuf[i+3] = calcFcs(l2capoutbuf);
|
||||
#ifdef EXTRADEBUG
|
||||
Serial.print(" - RFCOMM Data: ");
|
||||
Notify(PSTR(" - RFCOMM Data: "));
|
||||
for(i = 0; i < length+4; i++) {
|
||||
Serial.print(l2capoutbuf[i],HEX);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
}
|
||||
#endif
|
||||
RFCOMM_Command(l2capoutbuf,length+4);
|
||||
|
@ -1482,21 +1489,26 @@ void RFCOMM::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, ui
|
|||
l2capoutbuf[3] = credit; // Credit
|
||||
l2capoutbuf[4] = calcFcs(l2capoutbuf);
|
||||
#ifdef EXTRADEBUG
|
||||
Serial.print(" - RFCOMM Credit Data: ");
|
||||
Notify(PSTR(" - RFCOMM Credit Data: "));
|
||||
for(uint8_t i = 0; i < 5; i++) {
|
||||
Serial.print(l2capoutbuf[i],HEX);
|
||||
Serial.print(" ");
|
||||
Notify(PSTR(" "));
|
||||
}
|
||||
#endif
|
||||
RFCOMM_Command(l2capoutbuf,5);
|
||||
}
|
||||
|
||||
/* CRC on 2 bytes */
|
||||
uint8_t RFCOMM::__crc(uint8_t* data) {
|
||||
return(pgm_read_byte(&rfcomm_crc_table[pgm_read_byte(&rfcomm_crc_table[0xff ^ data[0]]) ^ data[1]]));
|
||||
}
|
||||
|
||||
/* Calculate FCS - we never actually check if the host sends correct FCS to the Arduino */
|
||||
uint8_t RFCOMM::calcFcs(uint8_t *data) {
|
||||
if((data[1] & 0xEF) == RFCOMM_UIH)
|
||||
return (0xff - __crc(data)); // FCS on 2 bytes
|
||||
else
|
||||
return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]); // FCS on 3 bytes
|
||||
return (0xff - pgm_read_byte(&rfcomm_crc_table[__crc(data) ^ data[2]])); // FCS on 3 bytes
|
||||
}
|
||||
|
||||
/* Serial commands */
|
||||
|
|
15
RFCOMM.h
15
RFCOMM.h
|
@ -180,12 +180,9 @@
|
|||
#define BT_RFCOMM_NSC_RSP 0x11
|
||||
*/
|
||||
|
||||
/* CRC on 2 bytes */
|
||||
#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
|
||||
|
||||
class RFCOMM : public USBDeviceConfig, public UsbConfigXtracter {
|
||||
public:
|
||||
RFCOMM(USB *p, const char* name = "Arduino", const char* key = "1234");
|
||||
RFCOMM(USB *p, const char* name = "Arduino", const char* pin = "1234");
|
||||
|
||||
// USBDeviceConfig implementation
|
||||
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
||||
|
@ -229,7 +226,7 @@ protected:
|
|||
|
||||
private:
|
||||
const char* btdName;
|
||||
const char* btdKey;
|
||||
const char* btdPin;
|
||||
|
||||
bool bPollEnable;
|
||||
uint8_t pollInterval;
|
||||
|
@ -276,11 +273,14 @@ private:
|
|||
uint8_t rfcommChannelType;
|
||||
uint8_t rfcommPfBit;
|
||||
|
||||
bool firstMessage;
|
||||
unsigned long timer;
|
||||
bool waitForLastCommand;
|
||||
|
||||
|
||||
uint8_t rfcommDataBuffer[256]; // Create a 256 sized buffer for incoming data
|
||||
uint8_t rfcommAvailable;
|
||||
uint8_t bufferPointer;
|
||||
|
||||
bool firstMessage; // Used to see if it's the first SDP request received
|
||||
|
||||
/* State machines */
|
||||
void HCI_event_task(); //poll the HCI event pipe
|
||||
|
@ -327,5 +327,6 @@ private:
|
|||
void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length);
|
||||
void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
|
||||
uint8_t calcFcs(uint8_t *data);
|
||||
uint8_t __crc(uint8_t* data);
|
||||
};
|
||||
#endif
|
Loading…
Reference in a new issue