USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
SPP.h
Go to the documentation of this file.
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 /* Bluetooth L2CAP states for SDP_task() */
24 #define L2CAP_SDP_WAIT 0
25 #define L2CAP_SDP_REQUEST 1
26 #define L2CAP_SDP_SUCCESS 2
27 #define L2CAP_SDP_DONE 3
28 #define L2CAP_DISCONNECT_RESPONSE 4
29 
30 /* Bluetooth L2CAP states for RFCOMM_task() */
31 #define L2CAP_RFCOMM_WAIT 0
32 #define L2CAP_RFCOMM_REQUEST 1
33 #define L2CAP_RFCOMM_SUCCESS 2
34 #define L2CAP_RFCOMM_DONE 3
35 
36 /* L2CAP event flags */
37 #define L2CAP_FLAG_CONNECTION_SDP_REQUEST 0x001
38 #define L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST 0x002
39 #define L2CAP_FLAG_CONFIG_SDP_REQUEST 0x004
40 #define L2CAP_FLAG_CONFIG_RFCOMM_REQUEST 0x008
41 #define L2CAP_FLAG_CONFIG_SDP_SUCCESS 0x010
42 #define L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS 0x020
43 #define L2CAP_FLAG_DISCONNECT_SDP_REQUEST 0x040
44 #define L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST 0x080
45 #define L2CAP_FLAG_DISCONNECT_RESPONSE 0x100
46 
47 /* Macros for L2CAP event flag tests */
48 #define l2cap_connection_request_sdp_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_SDP_REQUEST)
49 #define l2cap_connection_request_rfcomm_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST)
50 #define l2cap_config_request_sdp_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_SDP_REQUEST)
51 #define l2cap_config_request_rfcomm_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_RFCOMM_REQUEST)
52 #define l2cap_config_success_sdp_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_SDP_SUCCESS)
53 #define l2cap_config_success_rfcomm_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS)
54 #define l2cap_disconnect_request_sdp_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_SDP_REQUEST)
55 #define l2cap_disconnect_request_rfcomm_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST)
56 #define l2cap_disconnect_response_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_RESPONSE)
57 
58 /* Used for SDP */
59 #define SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU 0x06 // See the RFCOMM specs
60 #define SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU 0x07 // See the RFCOMM specs
61 #define SERIALPORT_UUID 0x1101 // See http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
62 #define L2CAP_UUID 0x0100
63 
64 /* Used for RFCOMM */
65 #define RFCOMM_SABM 0x2F
66 #define RFCOMM_UA 0x63
67 #define RFCOMM_UIH 0xEF
68 //#define RFCOMM_DM 0x0F
69 #define RFCOMM_DISC 0x43
70 
71 #define extendAddress 0x01 // Allways 1
72 
73 // Multiplexer message types
74 #define BT_RFCOMM_PN_CMD 0x83
75 #define BT_RFCOMM_PN_RSP 0x81
76 #define BT_RFCOMM_MSC_CMD 0xE3
77 #define BT_RFCOMM_MSC_RSP 0xE1
78 #define BT_RFCOMM_RPN_CMD 0x93
79 #define BT_RFCOMM_RPN_RSP 0x91
80 /*
81 #define BT_RFCOMM_TEST_CMD 0x23
82 #define BT_RFCOMM_TEST_RSP 0x21
83 #define BT_RFCOMM_FCON_CMD 0xA3
84 #define BT_RFCOMM_FCON_RSP 0xA1
85 #define BT_RFCOMM_FCOFF_CMD 0x63
86 #define BT_RFCOMM_FCOFF_RSP 0x61
87 #define BT_RFCOMM_RLS_CMD 0x53
88 #define BT_RFCOMM_RLS_RSP 0x51
89 #define BT_RFCOMM_NSC_RSP 0x11
90  */
91 
93 class SPP : public BluetoothService {
94 public:
101  SPP(BTD *p, const char* name = "Arduino", const char* pin = "1234");
102 
108  virtual void ACLData(uint8_t* ACLData);
110  virtual void Run();
112  virtual void Reset();
114  virtual void disconnect();
118  bool connected;
119 
125  void print(const String &str);
130  void println(const String &str);
131 
136  void print(const char* str);
141  void println(const char* str);
142 
147  void print(uint8_t data) {
148  print(&data, 1);
149  };
154  void println(uint8_t data);
155 
161  void print(uint8_t* array, uint8_t length);
167  void println(uint8_t* array, uint8_t length);
168 
174  void print(const __FlashStringHelper *ifsh) {
175  printFlashString(ifsh, false);
176  };
177 
182  void println(const __FlashStringHelper *ifsh) {
183  printFlashString(ifsh, true);
184  };
190  void printFlashString(const __FlashStringHelper *ifsh, bool newline);
191 
192 
194  void println(void);
195 
200  void printNumber(uint8_t n) {
201  printNumber((uint32_t) n);
202  };
203 
208  void printNumberln(uint8_t n) {
209  printNumberln((uint32_t) n);
210  };
211 
216  void printNumber(int8_t n) {
217  printNumber((int32_t) n);
218  };
219 
224  void printNumberln(int8_t n) {
225  printNumberln((int32_t) n);
226  };
227 
232  void printNumber(uint16_t n) {
233  printNumber((uint32_t) n);
234  };
235 
240  void printNumberln(uint16_t n) {
241  printNumberln((uint32_t) n);
242  };
243 
248  void printNumber(int16_t n) {
249  printNumber((int32_t) n);
250  };
251 
256  void printNumberln(int16_t n) {
257  printNumberln((int32_t) n);
258  };
259 
264  void printNumber(uint32_t n);
269  void printNumberln(uint32_t n);
270 
275  void printNumber(int32_t n);
280  void printNumberln(int32_t n);
281 
287  void intToString(int32_t input, char* output);
293  void intToString(uint32_t input, char* output);
294 
300  void printNumber(double n, uint8_t digits = 2);
306  void printNumberln(double n, uint8_t digits = 2);
313  void doubleToString(double input, char* output, uint8_t digits = 2);
314 
319  uint8_t available() {
320  return rfcommAvailable;
321  };
326  uint8_t read();
327 
329  void flush() {
330  rfcommAvailable = 0;
331  };
334 private:
335  /* Bluetooth dongle library pointer */
336  BTD *pBtd;
337 
338  /* Set true when a channel is created */
339  bool SDPConnected;
340  bool RFCOMMConnected;
341 
342  uint16_t hci_handle; // The HCI Handle for the connection
343 
344  /* Variables used by L2CAP state maschines */
345  uint8_t l2cap_sdp_state;
346  uint8_t l2cap_rfcomm_state;
347  uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events
348 
349  uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
350  uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
351 
352  /* L2CAP Channels */
353  uint8_t sdp_scid[2]; // L2CAP source CID for SDP
354  uint8_t sdp_dcid[2]; // 0x0050
355  uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
356  uint8_t rfcomm_dcid[2]; // 0x0051
357  uint8_t identifier; // Identifier for command
358 
359  /* RFCOMM Variables */
360  uint8_t rfcommChannel;
361  uint8_t rfcommChannelConnection; // This is the channel the SPP chanel will be running at
362  uint8_t rfcommDirection;
363  uint8_t rfcommCommandResponse;
364  uint8_t rfcommChannelType;
365  uint8_t rfcommPfBit;
366 
367  unsigned long timer;
368  bool waitForLastCommand;
369  bool creditSent;
370 
371  uint8_t rfcommDataBuffer[100]; // Create a 100 sized buffer for incoming data
372  uint8_t rfcommAvailable;
373 
374  bool firstMessage; // Used to see if it's the first SDP request received
375  uint8_t bytesRead; // Counter to see when it's time to send more credit
376 
377  /* State machines */
378  void SDP_task(); // SDP state machine
379  void RFCOMM_task(); // RFCOMM state machine
380 
381  /* SDP Commands */
382  void SDP_Command(uint8_t* data, uint8_t nbytes);
383  void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
384  void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
385  void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
386  void l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
387  void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow);
388 
389  /* RFCOMM Commands */
390  void RFCOMM_Command(uint8_t* data, uint8_t nbytes);
391  void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length);
392  void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit);
393  uint8_t calcFcs(uint8_t *data);
394  uint8_t __crc(uint8_t* data);
395 };
396 #endif