]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/protocol/usb_hid/USB_Host_Shield_2.0/SPP.h
lufa: usb-usb: Use LUFA startup instead of cusotom
[max/tmk_keyboard.git] / tmk_core / protocol / usb_hid / USB_Host_Shield_2.0 / SPP.h
1 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
2
3  This software may be distributed and modified under the terms of the GNU
4  General Public License version 2 (GPL2) as published by the Free Software
5  Foundation and appearing in the file GPL2.TXT included in the packaging of
6  this file. Please note that GPL2 Section 2[b] requires that all works based
7  on this software must also be made publicly available under the terms of
8  the GPL2 ("Copyleft").
9
10  Contact information
11  -------------------
12
13  Kristian Lauszus, TKJ Electronics
14  Web      :  http://www.tkjelectronics.com
15  e-mail   :  kristianl@tkjelectronics.com
16  */
17
18 #ifndef _spp_h_
19 #define _spp_h_
20
21 #include "BTD.h"
22
23 /* Used for SDP */
24 #define SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU    0x06 // See the RFCOMM specs
25 #define SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU   0x07 // See the RFCOMM specs
26 #define SERIALPORT_UUID     0x1101 // See http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
27 #define L2CAP_UUID          0x0100
28
29 /* Used for RFCOMM */
30 #define RFCOMM_SABM     0x2F
31 #define RFCOMM_UA       0x63
32 #define RFCOMM_UIH      0xEF
33 //#define RFCOMM_DM       0x0F
34 #define RFCOMM_DISC     0x43
35
36 #define extendAddress   0x01 // Always 1
37
38 // Multiplexer message types
39 #define BT_RFCOMM_PN_CMD     0x83
40 #define BT_RFCOMM_PN_RSP     0x81
41 #define BT_RFCOMM_MSC_CMD    0xE3
42 #define BT_RFCOMM_MSC_RSP    0xE1
43 #define BT_RFCOMM_RPN_CMD    0x93
44 #define BT_RFCOMM_RPN_RSP    0x91
45 /*
46 #define BT_RFCOMM_TEST_CMD   0x23
47 #define BT_RFCOMM_TEST_RSP   0x21
48 #define BT_RFCOMM_FCON_CMD   0xA3
49 #define BT_RFCOMM_FCON_RSP   0xA1
50 #define BT_RFCOMM_FCOFF_CMD  0x63
51 #define BT_RFCOMM_FCOFF_RSP  0x61
52 #define BT_RFCOMM_RLS_CMD    0x53
53 #define BT_RFCOMM_RLS_RSP    0x51
54 #define BT_RFCOMM_NSC_RSP    0x11
55  */
56
57 /**
58  * This BluetoothService class implements the Serial Port Protocol (SPP).
59  * It inherits the Arduino Stream class. This allows it to use all the standard Arduino print and stream functions.
60  */
61 class SPP : public BluetoothService, public Stream {
62 public:
63         /**
64          * Constructor for the SPP class.
65          * @param  p   Pointer to BTD class instance.
66          * @param  name   Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used.
67          * @param  pin   Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used.
68          */
69         SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
70
71         /** @name BluetoothService implementation */
72         /** Used this to disconnect the virtual serial port. */
73         void disconnect();
74         /**@}*/
75
76         /**
77          * Used to provide Boolean tests for the class.
78          * @return Return true if SPP communication is connected.
79          */
80         operator bool() {
81                 return connected;
82         }
83         /** Variable used to indicate if the connection is established. */
84         bool connected;
85
86         /** @name Serial port profile (SPP) Print functions */
87         /**
88          * Get number of bytes waiting to be read.
89          * @return Return the number of bytes ready to be read.
90          */
91         int available(void);
92
93         /** Send out all bytes in the buffer. */
94         void flush(void) {
95                 send();
96         };
97         /**
98          * Used to read the next value in the buffer without advancing to the next one.
99          * @return Return the byte. Will return -1 if no bytes are available.
100          */
101         int peek(void);
102         /**
103          * Used to read the buffer.
104          * @return Return the byte. Will return -1 if no bytes are available.
105          */
106         int read(void);
107
108 #if defined(ARDUINO) && ARDUINO >=100
109         /**
110          * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
111          * @param  data The byte to write.
112          * @return      Return the number of bytes written.
113          */
114         size_t write(uint8_t data);
115         /**
116          * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
117          * @param  data The data array to send.
118          * @param  size Size of the data.
119          * @return      Return the number of bytes written.
120          */
121         size_t write(const uint8_t* data, size_t size);
122         /** Pull in write(const char *str) from Print */
123         using Print::write;
124 #else
125         /**
126          * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
127          * @param  data The byte to write.
128          */
129         void write(uint8_t data);
130         /**
131          * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
132          * @param data The data array to send.
133          * @param size Size of the data.
134          */
135         void write(const uint8_t* data, size_t size);
136 #endif
137
138         /** Discard all the bytes in the buffer. */
139         void discard(void);
140         /**
141          * This will send all the bytes in the buffer.
142          * This is called whenever Usb.Task() is called,
143          * but can also be called via this function.
144          */
145         void send(void);
146         /**@}*/
147
148 protected:
149         /** @name BluetoothService implementation */
150         /**
151          * Used to pass acldata to the services.
152          * @param ACLData Incoming acldata.
153          */
154         void ACLData(uint8_t* ACLData);
155         /** Used to establish the connection automatically. */
156         void Run();
157         /** Use this to reset the service. */
158         void Reset();
159         /**
160          * Called when a device is successfully initialized.
161          * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
162          * This is useful for instance if you want to set the LEDs in a specific way.
163          */
164         void onInit();
165         /**@}*/
166
167 private:
168         /* Set true when a channel is created */
169         bool SDPConnected;
170         bool RFCOMMConnected;
171
172         /* Variables used by L2CAP state machines */
173         uint8_t l2cap_sdp_state;
174         uint8_t l2cap_rfcomm_state;
175
176         uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
177         uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
178
179         /* L2CAP Channels */
180         uint8_t sdp_scid[2]; // L2CAP source CID for SDP
181         uint8_t sdp_dcid[2]; // 0x0050
182         uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
183         uint8_t rfcomm_dcid[2]; // 0x0051
184
185         /* RFCOMM Variables */
186         uint8_t rfcommChannel;
187         uint8_t rfcommChannelConnection; // This is the channel the SPP channel will be running at
188         uint8_t rfcommDirection;
189         uint8_t rfcommCommandResponse;
190         uint8_t rfcommChannelType;
191         uint8_t rfcommPfBit;
192
193         uint32_t timer;
194         bool waitForLastCommand;
195         bool creditSent;
196
197         uint8_t rfcommDataBuffer[100]; // Create a 100 sized buffer for incoming data
198         uint8_t sppOutputBuffer[100]; // Create a 100 sized buffer for outgoing SPP data
199         uint8_t sppIndex;
200         uint8_t rfcommAvailable;
201
202         bool firstMessage; // Used to see if it's the first SDP request received
203         uint8_t bytesRead; // Counter to see when it's time to send more credit
204
205         /* State machines */
206         void SDP_task(); // SDP state machine
207         void RFCOMM_task(); // RFCOMM state machine
208
209         /* SDP Commands */
210         void SDP_Command(uint8_t *data, uint8_t nbytes);
211         void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
212         void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
213         void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
214         void l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
215         void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
216
217         /* RFCOMM Commands */
218         void RFCOMM_Command(uint8_t *data, uint8_t nbytes);
219         void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t *data, uint8_t length);
220         void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
221         uint8_t calcFcs(uint8_t *data);
222         bool checkFcs(uint8_t *data, uint8_t fcs);
223         uint8_t crc(uint8_t *data);
224 };
225 #endif