Takumi Odashima / ArduinoUsbHostShield

Dependents:   USBHOST_PS5

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPP.h Source File

SPP.h

00001 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
00002 
00003  This software may be distributed and modified under the terms of the GNU
00004  General Public License version 2 (GPL2) as published by the Free Software
00005  Foundation and appearing in the file GPL2.TXT included in the packaging of
00006  this file. Please note that GPL2 Section 2[b] requires that all works based
00007  on this software must also be made publicly available under the terms of
00008  the GPL2 ("Copyleft").
00009 
00010  Contact information
00011  -------------------
00012 
00013  Kristian Lauszus, TKJ Electronics
00014  Web      :  http://www.tkjelectronics.com
00015  e-mail   :  kristianl@tkjelectronics.com
00016  */
00017 
00018 #ifndef _spp_h_
00019 #define _spp_h_
00020 
00021 #include "BTD.h"
00022 
00023 /* Used for SDP */
00024 #define SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU    0x06 // See the RFCOMM specs
00025 #define SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU   0x07 // See the RFCOMM specs
00026 #define SERIALPORT_UUID     0x1101 // See http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
00027 #define L2CAP_UUID          0x0100
00028 
00029 /* Used for RFCOMM */
00030 #define RFCOMM_SABM     0x2F
00031 #define RFCOMM_UA       0x63
00032 #define RFCOMM_UIH      0xEF
00033 //#define RFCOMM_DM       0x0F
00034 #define RFCOMM_DISC     0x43
00035 
00036 #define extendAddress   0x01 // Always 1
00037 
00038 // Multiplexer message types
00039 #define BT_RFCOMM_PN_CMD     0x83
00040 #define BT_RFCOMM_PN_RSP     0x81
00041 #define BT_RFCOMM_MSC_CMD    0xE3
00042 #define BT_RFCOMM_MSC_RSP    0xE1
00043 #define BT_RFCOMM_RPN_CMD    0x93
00044 #define BT_RFCOMM_RPN_RSP    0x91
00045 /*
00046 #define BT_RFCOMM_TEST_CMD   0x23
00047 #define BT_RFCOMM_TEST_RSP   0x21
00048 #define BT_RFCOMM_FCON_CMD   0xA3
00049 #define BT_RFCOMM_FCON_RSP   0xA1
00050 #define BT_RFCOMM_FCOFF_CMD  0x63
00051 #define BT_RFCOMM_FCOFF_RSP  0x61
00052 #define BT_RFCOMM_RLS_CMD    0x53
00053 #define BT_RFCOMM_RLS_RSP    0x51
00054 #define BT_RFCOMM_NSC_RSP    0x11
00055  */
00056 
00057 /**
00058  * This BluetoothService class implements the Serial Port Protocol (SPP).
00059  * It inherits the Arduino Stream class. This allows it to use all the standard Arduino print and stream functions.
00060  */
00061 class SPP : public BluetoothService, public Stream {
00062 public:
00063         /**
00064          * Constructor for the SPP class.
00065          * @param  p   Pointer to BTD class instance.
00066          * @param  name   Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
00067          * @param  pin   Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used.
00068          */
00069         SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
00070 
00071         /** @name BluetoothService implementation */
00072         /** Used this to disconnect the virtual serial port. */
00073         void disconnect();
00074         /**@}*/
00075 
00076         /**
00077          * Used to provide Boolean tests for the class.
00078          * @return Return true if SPP communication is connected.
00079          */
00080         operator bool() {
00081                 return connected;
00082         }
00083         /** Variable used to indicate if the connection is established. */
00084         bool connected;
00085 
00086         /** @name Serial port profile (SPP) Print functions */
00087         /**
00088          * Get number of bytes waiting to be read.
00089          * @return Return the number of bytes ready to be read.
00090          */
00091         int available(void);
00092 
00093         /** Send out all bytes in the buffer. */
00094         void flush(void) {
00095                 send();
00096         };
00097         /**
00098          * Used to read the next value in the buffer without advancing to the next one.
00099          * @return Return the byte. Will return -1 if no bytes are available.
00100          */
00101         int peek(void);
00102         /**
00103          * Used to read the buffer.
00104          * @return Return the byte. Will return -1 if no bytes are available.
00105          */
00106         int read(void);
00107 
00108 #if defined(ARDUINO) && ARDUINO >=100
00109         /**
00110          * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
00111          * @param  data The byte to write.
00112          * @return      Return the number of bytes written.
00113          */
00114         size_t write(uint8_t data);
00115         /**
00116          * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
00117          * @param  data The data array to send.
00118          * @param  size Size of the data.
00119          * @return      Return the number of bytes written.
00120          */
00121         size_t write(const uint8_t* data, size_t size);
00122         /** Pull in write(const char *str) from Print */
00123         /*
00124 #if !defined(RBL_NRF51822)
00125         using Print::write;
00126 #endif*/
00127 
00128 #else
00129         /**
00130          * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
00131          * @param  data The byte to write.
00132          */
00133         void write(uint8_t data);
00134         /**
00135          * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
00136          * @param data The data array to send.
00137          * @param size Size of the data.
00138          */
00139         void write(const uint8_t* data, size_t size);
00140 #endif
00141 
00142         /** Discard all the bytes in the buffer. */
00143         void discard(void);
00144         /**
00145          * This will send all the bytes in the buffer.
00146          * This is called whenever Usb.Task() is called,
00147          * but can also be called via this function.
00148          */
00149         void send(void);
00150         /**@}*/
00151 
00152 protected:
00153         /** @name BluetoothService implementation */
00154         /**
00155          * Used to pass acldata to the services.
00156          * @param ACLData Incoming acldata.
00157          */
00158         void ACLData(uint8_t* ACLData);
00159         /** Used to establish the connection automatically. */
00160         void Run();
00161         /** Use this to reset the service. */
00162         void Reset();
00163         /**
00164          * Called when a device is successfully initialized.
00165          * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
00166          * This is useful for instance if you want to set the LEDs in a specific way.
00167          */
00168         void onInit();
00169         /**@}*/
00170 
00171 private:
00172         /* Set true when a channel is created */
00173         bool SDPConnected;
00174         bool RFCOMMConnected;
00175 
00176         /* Variables used by L2CAP state machines */
00177         uint8_t l2cap_sdp_state;
00178         uint8_t l2cap_rfcomm_state;
00179 
00180         uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
00181         uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
00182 
00183         /* L2CAP Channels */
00184         uint8_t sdp_scid[2]; // L2CAP source CID for SDP
00185         uint8_t sdp_dcid[2]; // 0x0050
00186         uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
00187         uint8_t rfcomm_dcid[2]; // 0x0051
00188 
00189         /* RFCOMM Variables */
00190         uint8_t rfcommChannel;
00191         uint8_t rfcommChannelConnection; // This is the channel the SPP channel will be running at
00192         uint8_t rfcommDirection;
00193         uint8_t rfcommCommandResponse;
00194         uint8_t rfcommChannelType;
00195         uint8_t rfcommPfBit;
00196 
00197         uint32_t timer;
00198         bool waitForLastCommand;
00199         bool creditSent;
00200 
00201         uint8_t rfcommDataBuffer[100]; // Create a 100 sized buffer for incoming data
00202         uint8_t sppOutputBuffer[100]; // Create a 100 sized buffer for outgoing SPP data
00203         uint8_t sppIndex;
00204         uint8_t rfcommAvailable;
00205 
00206         bool firstMessage; // Used to see if it's the first SDP request received
00207         uint8_t bytesRead; // Counter to see when it's time to send more credit
00208 
00209         /* State machines */
00210         void SDP_task(); // SDP state machine
00211         void RFCOMM_task(); // RFCOMM state machine
00212 
00213         /* SDP Commands */
00214         void SDP_Command(uint8_t *data, uint8_t nbytes);
00215         void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00216         void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00217         void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00218         void l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00219         void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00220 
00221         /* RFCOMM Commands */
00222         void RFCOMM_Command(uint8_t *data, uint8_t nbytes);
00223         void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t *data, uint8_t length);
00224         void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
00225         uint8_t calcFcs(uint8_t *data);
00226         bool checkFcs(uint8_t *data, uint8_t fcs);
00227         uint8_t crc(uint8_t *data);
00228 };
00229 #endif
00230