diff options
Diffstat (limited to 'lib/usbhost/USB_Host_Shield_2.0/SPP.h')
-rw-r--r-- | lib/usbhost/USB_Host_Shield_2.0/SPP.h | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/lib/usbhost/USB_Host_Shield_2.0/SPP.h b/lib/usbhost/USB_Host_Shield_2.0/SPP.h new file mode 100644 index 000000000..233ac611f --- /dev/null +++ b/lib/usbhost/USB_Host_Shield_2.0/SPP.h | |||
@@ -0,0 +1,225 @@ | |||
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 | ||