]> AND Private Git Repository - Cipher_code.git/blob - Arduino/libraries/Firmata/utility/BLEStream.h
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Merge branch 'master' of ssh://info.iut-bm.univ-fcomte.fr/Cipher_code
[Cipher_code.git] / Arduino / libraries / Firmata / utility / BLEStream.h
1 /*
2   BLEStream.h
3
4   Based on BLESerial.cpp by Voita Molda
5   https://github.com/sandeepmistry/arduino-BLEPeripheral/blob/master/examples/serial/BLESerial.h
6
7   Last updated April 4th, 2016
8  */
9
10 #ifndef _BLE_STREAM_H_
11 #define _BLE_STREAM_H_
12
13 #include <Arduino.h>
14 #if defined(_VARIANT_ARDUINO_101_X_)
15 #include <CurieBLE.h>
16 #define _MAX_ATTR_DATA_LEN_ BLE_MAX_ATTR_DATA_LEN
17 #else
18 #include <BLEPeripheral.h>
19 #define _MAX_ATTR_DATA_LEN_ BLE_ATTRIBUTE_MAX_VALUE_LENGTH
20 #endif
21
22 #define BLESTREAM_TXBUFFER_FLUSH_INTERVAL 80
23 #define BLESTREAM_MIN_FLUSH_INTERVAL 8 // minimum interval for flushing the TX buffer
24
25 // #define BLE_SERIAL_DEBUG
26
27 class BLEStream : public BLEPeripheral, public Stream
28 {
29   public:
30     BLEStream(unsigned char req = 0, unsigned char rdy = 0, unsigned char rst = 0);
31
32     void begin(...);
33     bool poll();
34     void end();
35     void setFlushInterval(int);
36
37     virtual int available(void);
38     virtual int peek(void);
39     virtual int read(void);
40     virtual void flush(void);
41     virtual size_t write(uint8_t byte);
42     using Print::write;
43     virtual operator bool();
44
45   private:
46     bool _connected;
47     unsigned long _flushed;
48     int _flushInterval;
49     static BLEStream* _instance;
50
51     size_t _rxHead;
52     size_t _rxTail;
53     size_t _rxCount() const;
54     unsigned char _rxBuffer[256];
55     size_t _txCount;
56     unsigned char _txBuffer[_MAX_ATTR_DATA_LEN_];
57
58     BLEService _uartService = BLEService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
59     BLEDescriptor _uartNameDescriptor = BLEDescriptor("2901", "UART");
60     BLECharacteristic _rxCharacteristic = BLECharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse, _MAX_ATTR_DATA_LEN_);
61     BLEDescriptor _rxNameDescriptor = BLEDescriptor("2901", "RX - Receive Data (Write)");
62     BLECharacteristic _txCharacteristic = BLECharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, _MAX_ATTR_DATA_LEN_);
63     BLEDescriptor _txNameDescriptor = BLEDescriptor("2901", "TX - Transfer Data (Notify)");
64
65     void _received(const unsigned char* data, size_t size);
66     static void _received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic);
67 };
68
69
70 /*
71  * BLEStream.cpp
72  * Copied here as a hack to avoid having to install the BLEPeripheral libarary even if it's
73  * not needed.
74  */
75
76 BLEStream* BLEStream::_instance = NULL;
77
78 BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) :
79 #if defined(_VARIANT_ARDUINO_101_X_)
80   BLEPeripheral()
81 #else
82   BLEPeripheral(req, rdy, rst)
83 #endif
84 {
85   this->_txCount = 0;
86   this->_rxHead = this->_rxTail = 0;
87   this->_flushed = 0;
88   this->_flushInterval = BLESTREAM_TXBUFFER_FLUSH_INTERVAL;
89   BLEStream::_instance = this;
90
91   addAttribute(this->_uartService);
92   addAttribute(this->_uartNameDescriptor);
93   setAdvertisedServiceUuid(this->_uartService.uuid());
94   addAttribute(this->_rxCharacteristic);
95   addAttribute(this->_rxNameDescriptor);
96   this->_rxCharacteristic.setEventHandler(BLEWritten, BLEStream::_received);
97   addAttribute(this->_txCharacteristic);
98   addAttribute(this->_txNameDescriptor);
99 }
100
101 void BLEStream::begin(...)
102 {
103   BLEPeripheral::begin();
104 #ifdef BLE_SERIAL_DEBUG
105   Serial.println(F("BLEStream::begin()"));
106 #endif
107 }
108
109 bool BLEStream::poll()
110 {
111   // BLEPeripheral::poll is called each time connected() is called
112   this->_connected = BLEPeripheral::connected();
113   if (millis() > this->_flushed + this->_flushInterval) {
114     flush();
115   }
116   return this->_connected;
117 }
118
119 void BLEStream::end()
120 {
121   this->_rxCharacteristic.setEventHandler(BLEWritten, (void(*)(BLECentral&, BLECharacteristic&))NULL);
122   this->_rxHead = this->_rxTail = 0;
123   flush();
124   BLEPeripheral::disconnect();
125 }
126
127 int BLEStream::available(void)
128 {
129 // BLEPeripheral::poll only calls delay(1) in CurieBLE so skipping it here to avoid the delay
130 #ifndef _VARIANT_ARDUINO_101_X_
131   // TODO Need to do more testing to determine if all of these calls to BLEPeripheral::poll are
132   // actually necessary. Seems to run fine without them, but only minimal testing so far.
133   BLEPeripheral::poll();
134 #endif
135   int retval = (this->_rxHead - this->_rxTail + sizeof(this->_rxBuffer)) % sizeof(this->_rxBuffer);
136 #ifdef BLE_SERIAL_DEBUG
137   if (retval > 0) {
138     Serial.print(F("BLEStream::available() = "));
139     Serial.println(retval);
140   }
141 #endif
142   return retval;
143 }
144
145 int BLEStream::peek(void)
146 {
147 #ifndef _VARIANT_ARDUINO_101_X_
148   BLEPeripheral::poll();
149 #endif
150   if (this->_rxTail == this->_rxHead) return -1;
151   uint8_t byte = this->_rxBuffer[this->_rxTail];
152 #ifdef BLE_SERIAL_DEBUG
153   Serial.print(F("BLEStream::peek() = 0x"));
154   Serial.println(byte, HEX);
155 #endif
156   return byte;
157 }
158
159 int BLEStream::read(void)
160 {
161 #ifndef _VARIANT_ARDUINO_101_X_
162   BLEPeripheral::poll();
163 #endif
164   if (this->_rxTail == this->_rxHead) return -1;
165   this->_rxTail = (this->_rxTail + 1) % sizeof(this->_rxBuffer);
166   uint8_t byte = this->_rxBuffer[this->_rxTail];
167 #ifdef BLE_SERIAL_DEBUG
168   Serial.print(F("BLEStream::read() = 0x"));
169   Serial.println(byte, HEX);
170 #endif
171   return byte;
172 }
173
174 void BLEStream::flush(void)
175 {
176   if (this->_txCount == 0) return;
177 #ifndef _VARIANT_ARDUINO_101_X_
178   // ensure there are available packets before sending
179   while(!this->_txCharacteristic.canNotify()) {
180     BLEPeripheral::poll();
181   }
182 #endif
183   this->_txCharacteristic.setValue(this->_txBuffer, this->_txCount);
184   this->_flushed = millis();
185   this->_txCount = 0;
186 #ifdef BLE_SERIAL_DEBUG
187   Serial.println(F("BLEStream::flush()"));
188 #endif
189 }
190
191 size_t BLEStream::write(uint8_t byte)
192 {
193 #ifndef _VARIANT_ARDUINO_101_X_
194   BLEPeripheral::poll();
195 #endif
196   if (this->_txCharacteristic.subscribed() == false) return 0;
197   this->_txBuffer[this->_txCount++] = byte;
198   if (this->_txCount == sizeof(this->_txBuffer)) flush();
199 #ifdef BLE_SERIAL_DEBUG
200   Serial.print(F("BLEStream::write( 0x"));
201   Serial.print(byte, HEX);
202   Serial.println(F(") = 1"));
203 #endif
204   return 1;
205 }
206
207 BLEStream::operator bool()
208 {
209   bool retval = this->_connected = BLEPeripheral::connected();
210 #ifdef BLE_SERIAL_DEBUG
211   Serial.print(F("BLEStream::operator bool() = "));
212   Serial.println(retval);
213 #endif
214   return retval;
215 }
216
217 void BLEStream::setFlushInterval(int interval)
218 {
219   if (interval > BLESTREAM_MIN_FLUSH_INTERVAL) {
220     this->_flushInterval = interval;
221   }
222 }
223
224 void BLEStream::_received(const unsigned char* data, size_t size)
225 {
226   for (size_t i = 0; i < size; i++) {
227     this->_rxHead = (this->_rxHead + 1) % sizeof(this->_rxBuffer);
228     this->_rxBuffer[this->_rxHead] = data[i];
229   }
230 #ifdef BLE_SERIAL_DEBUG
231   Serial.print(F("BLEStream::received("));
232   for (int i = 0; i < size; i++) Serial.print(data[i], HEX);
233   Serial.println(F(")"));
234 #endif
235 }
236
237 void BLEStream::_received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic)
238 {
239   BLEStream::_instance->_received(rxCharacteristic.value(), rxCharacteristic.valueLength());
240 }
241
242
243 #endif // _BLE_STREAM_H_