-
Notifications
You must be signed in to change notification settings - Fork 781
/
BTHID.h
188 lines (161 loc) · 6.65 KB
/
BTHID.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/* Copyright (C) 2013 Kristian Lauszus, TKJ Electronics. All rights reserved.
This software may be distributed and modified under the terms of the GNU
General Public License version 2 (GPL2) as published by the Free Software
Foundation and appearing in the file GPL2.TXT included in the packaging of
this file. Please note that GPL2 Section 2[b] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ("Copyleft").
Contact information
-------------------
Kristian Lauszus, TKJ Electronics
Web : http://www.tkjelectronics.com
e-mail : [email protected]
*/
#ifndef _bthid_h_
#define _bthid_h_
#include "BTD.h"
#include "hidboot.h"
#define KEYBOARD_PARSER_ID 0
#define MOUSE_PARSER_ID 1
#define NUM_PARSERS 2
/** This BluetoothService class implements support for Bluetooth HID devices. */
class BTHID : public BluetoothService {
public:
/**
* Constructor for the BTHID class.
* @param p Pointer to the BTD class instance.
* @param pair Set this to true in order to pair with the device. If the argument is omitted then it will not pair with it. One can use ::PAIR to set it to true.
* @param pin Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used.
*/
BTHID(BTD *p, bool pair = false, const char *pin = "0000");
/** @name BluetoothService implementation */
/** Used this to disconnect the devices. */
void disconnect();
/**@}*/
/**
* Get HIDReportParser.
* @param id ID of parser.
* @return Returns the corresponding HIDReportParser. Returns NULL if id is not valid.
*/
HIDReportParser *GetReportParser(uint8_t id) {
if (id >= NUM_PARSERS)
return NULL;
return pRptParser[id];
};
/**
* Set HIDReportParser to be used.
* @param id Id of parser.
* @param prs Pointer to HIDReportParser.
* @return Returns true if the HIDReportParser is set. False otherwise.
*/
bool SetReportParser(uint8_t id, HIDReportParser *prs) {
if (id >= NUM_PARSERS)
return false;
pRptParser[id] = prs;
return true;
};
/**
* Set HID protocol mode.
* @param mode HID protocol to use. Either USB_HID_BOOT_PROTOCOL or HID_RPT_PROTOCOL.
*/
void setProtocolMode(uint8_t mode) {
protocolMode = mode;
};
/**@{*/
/**
* Used to set the leds on a keyboard.
* @param data See ::KBDLEDS in hidboot.h
*/
void setLeds(struct KBDLEDS data) {
setLeds(*((uint8_t*)&data));
};
void setLeds(uint8_t data);
/**@}*/
/** True if a device is connected */
bool connected;
/** Call this to start the pairing sequence with a device */
void pair(void) {
if(pBtd)
pBtd->pairWithHID();
};
/**
* Used to get the millis() of the last Bluetooth DATA input report received on the interrupt channel.
* This can be used detect if the connection to a Bluetooth device is lost fx if the battery runs out or if it gets out of range.
* @return Timestamp in milliseconds of the last Bluetooth DATA input report received on the interrupt channel.
*/
uint32_t getLastMessageTime() {
return lastBtDataInputIntMillis;
};
protected:
/** @name BluetoothService implementation */
/**
* Used to pass acldata to the services.
* @param ACLData Incoming acldata.
*/
void ACLData(uint8_t* ACLData);
/** Used to run part of the state machine. */
void Run();
/** Use this to reset the service. */
void Reset();
/**
* Called when a device is successfully initialized.
* Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
* This is useful for instance if you want to set the LEDs in a specific way.
*/
void onInit() {
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
OnInitBTHID();
};
/**@}*/
/** @name Overridable functions */
/**
* Used to parse Bluetooth HID data to any class that inherits this class.
* @param len The length of the incoming data.
* @param buf Pointer to the data buffer.
*/
virtual void ParseBTHIDData(uint8_t len __attribute__((unused)), uint8_t *buf __attribute__((unused))) {
return;
};
/**
* Same as ParseBTHIDData for reports that are sent through the
* interrupt pipe (in response to a GET_REPORT).
*/
virtual void ParseBTHIDControlData(uint8_t len __attribute__((unused)), uint8_t *buf __attribute__((unused))) {
return;
}
/** Called when a device is connected */
virtual void OnInitBTHID() {
return;
};
/** Used to reset any buffers in the class that inherits this */
virtual void ResetBTHID() {
return;
}
/**@}*/
/** L2CAP source CID for HID_Control */
uint8_t control_scid[2];
/** L2CAP source CID for HID_Interrupt */
uint8_t interrupt_scid[2];
uint8_t l2cap_sdp_state;
uint8_t sdp_scid[2]; // L2CAP source CID for SDP
private:
HIDReportParser *pRptParser[NUM_PARSERS]; // Pointer to HIDReportParsers.
uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
void SDP_Command(uint8_t* data, uint8_t nbytes);
void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow);
/** Set report protocol. */
void setProtocol();
uint8_t protocolMode;
void SDP_task();
void L2CAP_task(); // L2CAP state machine
bool activeConnection; // Used to indicate if it already has established a connection
bool SDPConnected;
/* Variables used for L2CAP communication */
uint8_t control_dcid[2]; // L2CAP device CID for HID_Control - Always 0x0070
uint8_t interrupt_dcid[2]; // L2CAP device CID for HID_Interrupt - Always 0x0071
uint8_t sdp_dcid[2];
uint8_t l2cap_state;
uint32_t lastBtDataInputIntMillis; // Variable used to store the millis value of the last Bluetooth DATA input report received on the interrupt channel
};
#endif