|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : [email protected]
- */
-
- #ifndef _spp_h_
- #define _spp_h_
-
- #include "BTD.h"
-
- /* Used for SDP */
- #define SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU 0x06 // See the RFCOMM specs
- #define SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU 0x07 // See the RFCOMM specs
- #define SERIALPORT_UUID 0x1101 // See http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
- #define L2CAP_UUID 0x0100
-
- /* Used for RFCOMM */
- #define RFCOMM_SABM 0x2F
- #define RFCOMM_UA 0x63
- #define RFCOMM_UIH 0xEF
- //#define RFCOMM_DM 0x0F
- #define RFCOMM_DISC 0x43
-
- #define extendAddress 0x01 // Always 1
-
- // Multiplexer message types
- #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
- /*
- #define BT_RFCOMM_TEST_CMD 0x23
- #define BT_RFCOMM_TEST_RSP 0x21
- #define BT_RFCOMM_FCON_CMD 0xA3
- #define BT_RFCOMM_FCON_RSP 0xA1
- #define BT_RFCOMM_FCOFF_CMD 0x63
- #define BT_RFCOMM_FCOFF_RSP 0x61
- #define BT_RFCOMM_RLS_CMD 0x53
- #define BT_RFCOMM_RLS_RSP 0x51
- #define BT_RFCOMM_NSC_RSP 0x11
- */
-
- /**
- * This BluetoothService class implements the Serial Port Protocol (SPP).
- * It inherits the Arduino Stream class. This allows it to use all the standard Arduino print and stream functions.
- */
- class SPP : public BluetoothService, public Stream {
- public:
- /**
- * Constructor for the SPP class.
- * @param p Pointer to BTD class instance.
- * @param name Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
- * @param pin Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used.
- */
- SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
-
- /** @name BluetoothService implementation */
- /** Used this to disconnect the virtual serial port. */
- void disconnect();
- /**@}*/
-
- /**
- * Used to provide Boolean tests for the class.
- * @return Return true if SPP communication is connected.
- */
- operator bool() {
- return connected;
- }
- /** Variable used to indicate if the connection is established. */
- bool connected;
-
- /** @name Serial port profile (SPP) Print functions */
- /**
- * Get number of bytes waiting to be read.
- * @return Return the number of bytes ready to be read.
- */
- int available(void);
-
- /** Send out all bytes in the buffer. */
- void flush(void) {
- send();
- };
- /**
- * Used to read the next value in the buffer without advancing to the next one.
- * @return Return the byte. Will return -1 if no bytes are available.
- */
- int peek(void);
- /**
- * Used to read the buffer.
- * @return Return the byte. Will return -1 if no bytes are available.
- */
- int read(void);
-
- #if defined(ARDUINO) && ARDUINO >=100
- /**
- * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
- * @param data The byte to write.
- * @return Return the number of bytes written.
- */
- size_t write(uint8_t data);
- /**
- * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
- * @param data The data array to send.
- * @param size Size of the data.
- * @return Return the number of bytes written.
- */
- size_t write(const uint8_t* data, size_t size);
- /** Pull in write(const char *str) from Print */
- using Print::write;
- #else
- /**
- * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
- * @param data The byte to write.
- */
- void write(uint8_t data);
- /**
- * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
- * @param data The data array to send.
- * @param size Size of the data.
- */
- void write(const uint8_t* data, size_t size);
- #endif
-
- /** Discard all the bytes in the buffer. */
- void discard(void);
- /**
- * This will send all the bytes in the buffer.
- * This is called whenever Usb.Task() is called,
- * but can also be called via this function.
- */
- void send(void);
- /**@}*/
-
- protected:
- /** @name BluetoothService implementation */
- /**
- * Used to pass acldata to the services.
- * @param ACLData Incoming acldata.
- */
- void ACLData(uint8_t* ACLData);
- /** Used to establish the connection automatically. */
- void Run();
- /** Use this to reset the service. */
- void Reset();
- /**
- * Called when a device is successfully initialized.
- * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
- * This is useful for instance if you want to set the LEDs in a specific way.
- */
- void onInit();
- /**@}*/
-
- private:
- /* Set true when a channel is created */
- bool SDPConnected;
- bool RFCOMMConnected;
-
- /* Variables used by L2CAP state machines */
- uint8_t l2cap_sdp_state;
- uint8_t l2cap_rfcomm_state;
-
- uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
- uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
-
- /* L2CAP Channels */
- uint8_t sdp_scid[2]; // L2CAP source CID for SDP
- uint8_t sdp_dcid[2]; // 0x0050
- uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
- uint8_t rfcomm_dcid[2]; // 0x0051
-
- /* RFCOMM Variables */
- uint8_t rfcommChannel;
- uint8_t rfcommChannelConnection; // This is the channel the SPP channel will be running at
- uint8_t rfcommDirection;
- uint8_t rfcommCommandResponse;
- uint8_t rfcommChannelType;
- uint8_t rfcommPfBit;
-
- uint32_t timer;
- bool waitForLastCommand;
- bool creditSent;
-
- uint8_t rfcommDataBuffer[100]; // Create a 100 sized buffer for incoming data
- uint8_t sppOutputBuffer[100]; // Create a 100 sized buffer for outgoing SPP data
- uint8_t sppIndex;
- uint8_t rfcommAvailable;
-
- bool firstMessage; // Used to see if it's the first SDP request received
- uint8_t bytesRead; // Counter to see when it's time to send more credit
-
- /* State machines */
- void SDP_task(); // SDP state machine
- void RFCOMM_task(); // RFCOMM state machine
-
- /* SDP Commands */
- 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);
-
- /* RFCOMM Commands */
- 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
|