Zoltan Hudak / UsbHostMAX3421E

Dependents:   UsbHostMAX3421E_Hello

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 class SPP : public BluetoothService {
00063 public:
00064         /**
00065          * Constructor for the SPP class.
00066          * @param  p   Pointer to BTD class instance.
00067          * @param  name   Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
00068          * @param  pin   Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used.
00069          */
00070         SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
00071 
00072         /** @name BluetoothService implementation */
00073         /** Used this to disconnect the virtual serial port. */
00074         void disconnect();
00075         /**@}*/
00076 
00077         /**
00078          * Used to provide Boolean tests for the class.
00079          * @return Return true if SPP communication is connected.
00080          */
00081         operator bool() {
00082                 return connected;
00083         }
00084         /** Variable used to indicate if the connection is established. */
00085         bool connected;
00086 
00087         /** @name Serial port profile (SPP) Print functions */
00088         /**
00089          * Get number of bytes waiting to be read.
00090          * @return Return the number of bytes ready to be read.
00091          */
00092         int available(void);
00093 
00094         /** Send out all bytes in the buffer. */
00095         void flush(void) {
00096                 send();
00097         };
00098         /**
00099          * Used to read the next value in the buffer without advancing to the next one.
00100          * @return Return the byte. Will return -1 if no bytes are available.
00101          */
00102         int peek(void);
00103         /**
00104          * Used to read the buffer.
00105          * @return Return the byte. Will return -1 if no bytes are available.
00106          */
00107         int read(void);
00108 
00109 #if defined(ARDUINO) && ARDUINO >=100
00110         /**
00111          * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
00112          * @param  data The byte to write.
00113          * @return      Return the number of bytes written.
00114          */
00115         size_t write(uint8_t data);
00116         /**
00117          * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
00118          * @param  data The data array to send.
00119          * @param  size Size of the data.
00120          * @return      Return the number of bytes written.
00121          */
00122         size_t write(const uint8_t* data, size_t size);
00123         /** Pull in write(const char *str) from Print */
00124 #if !defined(RBL_NRF51822)
00125         using Print::write;
00126 #endif
00127 #else
00128         /**
00129          * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
00130          * @param  data The byte to write.
00131          */
00132         void write(uint8_t data);
00133         /**
00134          * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
00135          * @param data The data array to send.
00136          * @param size Size of the data.
00137          */
00138         void write(const uint8_t* data, size_t size);
00139 #endif
00140 
00141         /** Discard all the bytes in the buffer. */
00142         void discard(void);
00143         /**
00144          * This will send all the bytes in the buffer.
00145          * This is called whenever Usb.Task() is called,
00146          * but can also be called via this function.
00147          */
00148         void send(void);
00149         /**@}*/
00150 
00151 protected:
00152         /** @name BluetoothService implementation */
00153         /**
00154          * Used to pass acldata to the services.
00155          * @param ACLData Incoming acldata.
00156          */
00157         void ACLData(uint8_t* ACLData);
00158         /** Used to establish the connection automatically. */
00159         void Run();
00160         /** Use this to reset the service. */
00161         void Reset();
00162         /**
00163          * Called when a device is successfully initialized.
00164          * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
00165          * This is useful for instance if you want to set the LEDs in a specific way.
00166          */
00167         void onInit();
00168         /**@}*/
00169 
00170 private:
00171         /* Set true when a channel is created */
00172         bool SDPConnected;
00173         bool RFCOMMConnected;
00174 
00175         /* Variables used by L2CAP state machines */
00176         uint8_t l2cap_sdp_state;
00177         uint8_t l2cap_rfcomm_state;
00178 
00179         uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
00180         uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
00181 
00182         /* L2CAP Channels */
00183         uint8_t sdp_scid[2]; // L2CAP source CID for SDP
00184         uint8_t sdp_dcid[2]; // 0x0050
00185         uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
00186         uint8_t rfcomm_dcid[2]; // 0x0051
00187 
00188         /* RFCOMM Variables */
00189         uint8_t rfcommChannel;
00190         uint8_t rfcommChannelConnection; // This is the channel the SPP channel will be running at
00191         uint8_t rfcommDirection;
00192         uint8_t rfcommCommandResponse;
00193         uint8_t rfcommChannelType;
00194         uint8_t rfcommPfBit;
00195 
00196         uint32_t timer;
00197         bool waitForLastCommand;
00198         bool creditSent;
00199 
00200         uint8_t rfcommDataBuffer[100]; // Create a 100 sized buffer for incoming data
00201         uint8_t sppOutputBuffer[100]; // Create a 100 sized buffer for outgoing SPP data
00202         uint8_t sppIndex;
00203         uint8_t rfcommAvailable;
00204 
00205         bool firstMessage; // Used to see if it's the first SDP request received
00206         uint8_t bytesRead; // Counter to see when it's time to send more credit
00207 
00208         /* State machines */
00209         void SDP_task(); // SDP state machine
00210         void RFCOMM_task(); // RFCOMM state machine
00211 
00212         /* SDP Commands */
00213         void SDP_Command(uint8_t *data, uint8_t nbytes);
00214         void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00215         void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00216         void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00217         void l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00218         void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
00219 
00220         /* RFCOMM Commands */
00221         void RFCOMM_Command(uint8_t *data, uint8_t nbytes);
00222         void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t *data, uint8_t length);
00223         void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
00224         uint8_t calcFcs(uint8_t *data);
00225         bool checkFcs(uint8_t *data, uint8_t fcs);
00226         uint8_t crc(uint8_t *data);
00227 };
00228 #endif