#ifndef _spp_h_
#define _spp_h_
#include "BTD.h"
#define SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU 0x06
#define SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU 0x07
#define SERIALPORT_UUID 0x1101
#define L2CAP_UUID 0x0100
#define RFCOMM_SABM 0x2F
#define RFCOMM_UA 0x63
#define RFCOMM_UIH 0xEF
#define RFCOMM_DISC 0x43
#define extendAddress 0x01
#define BT_RFCOMM_PN_CMD 0x83
#define BT_RFCOMM_PN_RSP 0x81
#define BT_RFCOMM_MSC_CMD 0xE3
#define BT_RFCOMM_MSC_RSP 0xE1
#define BT_RFCOMM_RPN_CMD 0x93
#define BT_RFCOMM_RPN_RSP 0x91
class SPP : public BluetoothService, public Stream {
public:
SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
void disconnect();
operator bool() {
return connected;
}
bool connected;
int available(void);
void flush(void) {
send();
};
int peek(void);
int read(void);
#if defined(ARDUINO) && ARDUINO >=100
size_t write(uint8_t data);
size_t write(const uint8_t* data, size_t size);
using Print::write;
#else
void write(uint8_t data);
void write(const uint8_t* data, size_t size);
#endif
void discard(void);
void send(void);
protected:
void ACLData(uint8_t* ACLData);
void Run();
void Reset();
void onInit();
private:
bool SDPConnected;
bool RFCOMMConnected;
uint8_t l2cap_sdp_state;
uint8_t l2cap_rfcomm_state;
uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; uint8_t rfcommbuf[10];
uint8_t sdp_scid[2]; uint8_t sdp_dcid[2]; uint8_t rfcomm_scid[2]; uint8_t rfcomm_dcid[2];
uint8_t rfcommChannel;
uint8_t rfcommChannelConnection; uint8_t rfcommDirection;
uint8_t rfcommCommandResponse;
uint8_t rfcommChannelType;
uint8_t rfcommPfBit;
uint32_t timer;
bool waitForLastCommand;
bool creditSent;
uint8_t rfcommDataBuffer[100]; uint8_t sppOutputBuffer[100]; uint8_t sppIndex;
uint8_t rfcommAvailable;
bool firstMessage; uint8_t bytesRead;
void SDP_task(); void RFCOMM_task();
void SDP_Command(uint8_t *data, uint8_t nbytes);
void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
void RFCOMM_Command(uint8_t *data, uint8_t nbytes);
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);
bool checkFcs(uint8_t *data, uint8_t fcs);
uint8_t crc(uint8_t *data);
};
#endif