ESP3D  3.0
Firmware for ESP boards connected to 3D Printer
BT_service.cpp
Go to the documentation of this file.
1 /*
2  BT_service.cpp - Bluetooth service functions class
3 
4  Copyright (c) 2014 Luc Lebosse. All rights reserved.
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
21 #ifdef ARDUINO_ARCH_ESP32
22 
23 #include "../../include/esp3d_config.h"
24 
25 #ifdef BLUETOOTH_FEATURE
26 #include "BluetoothSerial.h"
27 #include "../../core/esp3doutput.h"
28 #include "../../core/settings_esp3d.h"
29 #include "../../core/commands.h"
30 #include "../network/netconfig.h"
31 #include "BT_service.h"
32 BluetoothSerial SerialBT;
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 const uint8_t *esp_bt_dev_get_address(void);
37 #ifdef __cplusplus
38 }
39 #endif
40 
41 #define TIMEOUT_BT_FLUSH 1500
42 
44 
45 String BTService::_btname = "";
46 String BTService::_btclient = "";
47 
49 {
50  _buffer_size = 0;
51 }
52 
54 {
55  end();
56 }
57 
59 {
60  return ((_btclient.length() > 0)?true:false);
61 }
62 
63 void BTService::setClientAddress(const char * saddress)
64 {
65  _btclient = saddress;
66 }
67 
68 static void my_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
69 {
71  switch (event) {
72  case ESP_SPP_SRV_OPEN_EVT: {
73  //Server connection open
74  char str[18];
75  str[17]='\0';
76  uint8_t * addr = param->srv_open.rem_bda;
77  sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
79  String stmp = "BT Connected with ";
80  stmp += str;
81  output.printMSG(stmp.c_str());
82 #if defined (DISPLAY_DEVICE)
83  ESP3DOutput outputscr(ESP_SCREEN_CLIENT);
84  outputscr.printMSG(stmp.c_str());
85 #endif //DISPLAY_DEVICE
86  }
87  break;
88 
89  case ESP_SPP_CLOSE_EVT: {
90  //Client connection closed
91  output.printMSG("BT Disconnected");
92 #if defined (DISPLAY_DEVICE)
93  ESP3DOutput outputscr(ESP_SCREEN_CLIENT);
94  outputscr.printMSG("BT Disconnected");
95 #endif //DISPLAY_DEVICE
97  }
98  break;
99  default:
100  break;
101  }
102 }
103 
104 const char* BTService::macAddress()
105 {
106  const uint8_t* point = esp_bt_dev_get_address();
107  static char str[18];
108  str[17]='\0';
109  sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", (int)point[0], (int)point[1], (int)point[2], (int)point[3], (int)point[4], (int)point[5]);
110  return str;
111 }
112 
113 const char* BTService::clientmacAddress()
114 {
115  return _btclient.c_str();
116 }
117 
121 bool BTService::begin()
122 {
124  bool res = true;
125  _buffer_size = 0;
126  _lastflush = millis();
127  //stop BT Serial if active
128  end();
129  //Get hostname
130  //this allow to adjust if necessary
133  if (!SerialBT.begin(_btname)) {
134  output.printERROR("BT failed start");
135  res = false;
136  } else {
137  SerialBT.register_callback(&my_spp_cb);
138  String stmp = "BT Started with: '" + _btname + "'";
139  output.printMSG(stmp.c_str());
140  }
141  }
142  return res;
143 }
144 
148 void BTService::end()
149 {
150  flush();
151  SerialBT.end();
153  output.printMSG("Bluetooth Off");
154  _buffer_size = 0;
155 }
156 
160 bool BTService::reset()
161 {
162  //nothing to reset
163  return true;
164 }
165 
169 bool BTService::started()
170 {
171  return btStarted();
172 }
173 
177 void BTService::handle()
178 {
179  //Do we have some data waiting
180  size_t len = SerialBT.available();
181  if (len > 0) {
182  //if yes read them
183  uint8_t * sbuf = (uint8_t *)malloc(len);
184  if(sbuf) {
185  size_t count = readBytes(sbuf, len);
186  //push to buffer
187  if (count > 0) {
188  push2buffer(sbuf, count);
189  }
190  //freen buffer
191  free(sbuf);
192  }
193  }
194  //we cannot left data in buffer too long
195  //in case some commands "forget" to add \n
196  if (((millis() - _lastflush) > TIMEOUT_BT_FLUSH) && (_buffer_size > 0)) {
197  flushbuffer();
198  }
199 }
200 
201 void BTService::flushbuffer()
202 {
203  ESP3DOutput output(ESP_BT_CLIENT);
204  _buffer[_buffer_size] = 0x0;
205  //dispatch command
206  esp3d_commands.process(_buffer, _buffer_size, &output);
207  _lastflush = millis();
208  _buffer_size = 0;
209 }
210 
211 //push collected data to buffer and proceed accordingly
212 void BTService::push2buffer(uint8_t * sbuf, size_t len)
213 {
214  for (size_t i = 0; i < len; i++) {
215  _lastflush = millis();
216  //command is defined
217  if (char(sbuf[i]) == '\n') {
218  if (_buffer_size < ESP3D_BT_BUFFER_SIZE) {
219  _buffer[_buffer_size] = sbuf[i];
220  _buffer_size++;
221  }
222  flushbuffer();
223  } else if (isPrintable (char(sbuf[i]) ) || char(sbuf[i]) == '\r') {
224  if (_buffer_size < ESP3D_BT_BUFFER_SIZE) {
225  _buffer[_buffer_size] = sbuf[i];
226  _buffer_size++;
227  } else {
228  flushbuffer();
229  _buffer[_buffer_size] = sbuf[i];
230  _buffer_size++;
231  }
232  } else { //it is not printable char
233  //clean buffer first
234  if (_buffer_size > 0) {
235  flushbuffer();
236  }
237  //process char
238  _buffer[_buffer_size] = sbuf[i];
239  _buffer_size++;
240  flushbuffer();
241  }
242  }
243 }
244 
245 size_t BTService::write(uint8_t c)
246 {
247  return SerialBT.write(c);
248 }
249 
250 size_t BTService::write(const uint8_t *buffer, size_t size)
251 {
252  if (availableForWrite() >= size) {
253  return SerialBT.write(buffer, size);
254  } else {
255  size_t sizetosend = size;
256  size_t sizesent = 0;
257  uint8_t *buffertmp=(uint8_t *)buffer;
258  uint32_t starttime = millis();
259  //loop until all is sent or timeout
260  while (sizetosend>0 && ((millis() - starttime) < 100)) {
261  size_t available = availableForWrite();
262  if(available>0) {
263  //in case less is sent
264  available = SerialBT.write(&buffertmp[sizesent], (available >= sizetosend)?sizetosend:available);
265  sizetosend-=available;
266  sizesent+=available;
267  starttime=millis();
268  } else {
269  Hal::wait(5);
270  }
271  }
272  return sizesent;
273  }
274 }
275 
277 {
278  return 128;//SerialBT.availableForWrite();
279 }
280 
282 {
283  return SerialBT.available();
284 }
285 
286 int BTService::read()
287 {
288  return SerialBT.read();
289 }
290 
291 size_t BTService::readBytes(uint8_t * sbuf, size_t len)
292 {
293  return SerialBT.readBytes(sbuf, len);
294 }
295 
296 void BTService::flush()
297 {
298  SerialBT.flush();
299 }
300 
301 const char * BTService::hostname()
302 {
303  return _btname.c_str();
304 }
305 
306 #endif // BLUETOOTH_FEATURE
307 
308 #endif // ARDUINO_ARCH_ESP32
esp3d_commands
Commands esp3d_commands
Definition: commands.cpp:26
BTService::clientmacAddress
static const char * clientmacAddress()
BTService::available
int available()
Settings_ESP3D::read_string
static const char * read_string(int pos, bool *haserror=NULL)
Definition: settings_esp3d.cpp:794
Hal::wait
static void wait(uint32_t milliseconds)
Definition: hal.cpp:226
BT_service.h
ESP3D_BT_BUFFER_SIZE
#define ESP3D_BT_BUFFER_SIZE
Definition: BT_service.h:25
BTService::end
void end()
Commands::process
void process(uint8_t *sbuf, size_t len, ESP3DOutput *output, level_authenticate_type auth=LEVEL_GUEST, ESP3DOutput *outputonly=nullptr)
Definition: commands.cpp:36
BTService::macAddress
static const char * macAddress()
BTService
Definition: BT_service.h:27
BTService::setClientAddress
static void setClientAddress(const char *saddress)
BTService::~BTService
~BTService()
BTService::availableForWrite
int availableForWrite()
BTService::begin
bool begin()
BTService::write
size_t write(uint8_t c)
ESP_HOSTNAME
#define ESP_HOSTNAME
Definition: settings_esp3d.h:55
BTService::flush
void flush()
BTService::read
int read()
ESP_BT
#define ESP_BT
Definition: netconfig.h:43
BTService::reset
bool reset()
BTService::handle
void handle()
ESP_SCREEN_CLIENT
#define ESP_SCREEN_CLIENT
Definition: esp3doutput.h:28
BTService::started
bool started()
Settings_ESP3D::read_byte
static uint8_t read_byte(int pos, bool *haserror=NULL)
Definition: settings_esp3d.cpp:715
ESP_ALL_CLIENTS
#define ESP_ALL_CLIENTS
Definition: esp3doutput.h:30
BTService::readBytes
size_t readBytes(uint8_t *sbuf, size_t len)
bt_service
BTService bt_service
BTService::isConnected
bool isConnected()
BTService::hostname
const char * hostname()
ESP_BT_CLIENT
#define ESP_BT_CLIENT
Definition: esp3doutput.h:27
ESP3DOutput
Definition: esp3doutput.h:48
ESP_RADIO_MODE
#define ESP_RADIO_MODE
Definition: settings_esp3d.h:39
BTService::BTService
BTService()