8#include "BufferedAsyncSerial.h"
14#include <boost/bind/bind.hpp>
24BufferedAsyncSerial::BufferedAsyncSerial() :
AsyncSerial()
26 setReadCallback(boost::bind(&BufferedAsyncSerial::readCallback,
this, boost::placeholders::_1, boost::placeholders::_2));
29BufferedAsyncSerial::BufferedAsyncSerial(
const std::string& devname,
30 unsigned int baud_rate,
31 asio::serial_port_base::parity opt_parity,
32 asio::serial_port_base::character_size opt_csize,
33 asio::serial_port_base::flow_control opt_flow,
34 asio::serial_port_base::stop_bits opt_stop)
35 :
AsyncSerial(devname, baud_rate, opt_parity, opt_csize, opt_flow, opt_stop)
37 setReadCallback(boost::bind(&BufferedAsyncSerial::readCallback,
this, boost::placeholders::_1, boost::placeholders::_2));
42 boost::lock_guard<boost::mutex> l(readQueueMutex);
43 size_t result = min(size, readQueue.size());
44 vector<char>::iterator it = readQueue.begin() + result;
45 copy(readQueue.begin(), it, data);
46 readQueue.erase(readQueue.begin(), it);
52 boost::lock_guard<boost::mutex> l(readQueueMutex);
54 result.swap(readQueue);
60 boost::lock_guard<boost::mutex> l(readQueueMutex);
61 string result(readQueue.begin(), readQueue.end());
68 boost::lock_guard<boost::mutex> l(readQueueMutex);
69 vector<char>::iterator it = findStringInVector(readQueue, delim);
70 if (it == readQueue.end())
return "";
71 string result(readQueue.begin(), it);
73 readQueue.erase(readQueue.begin(), it);
77void BufferedAsyncSerial::readCallback(
const char *data,
size_t len)
79 boost::lock_guard<boost::mutex> l(readQueueMutex);
80 readQueue.insert(readQueue.end(), data, data + len);
83 std::string* buffer =
new std::string(readQueue.begin(), readQueue.end());
84 OBJpostEvent(SERIAL_READ_CB, SCOL_PTR
this, SCOL_PTR buffer);
88std::vector<char>::iterator BufferedAsyncSerial::findStringInVector(
89 std::vector<char>& v,
const std::string& s)
91 if (s.size() == 0)
return v.end();
93 vector<char>::iterator it = v.begin();
96 vector<char>::iterator result = find(it, v.end(), s[0]);
97 if (result == v.end())
return v.end();
99 for (
size_t i = 0; i < s.size(); i++)
101 vector<char>::iterator temp = result + i;
102 if (temp == v.end())
return v.end();
103 if (s[i] != *temp)
goto mismatch;
113BufferedAsyncSerial::~BufferedAsyncSerial()
118BufferedAsyncSerial::BufferedAsyncSerial()
123 mThread = boost::thread(boost::bind(&BufferedAsyncSerial::cbThread,
this));
126BufferedAsyncSerial::BufferedAsyncSerial(
const std::string& devname)
131 mThread = boost::thread(boost::bind(&BufferedAsyncSerial::cbThread,
this));
134BufferedAsyncSerial::~BufferedAsyncSerial()
137 if (mThread.joinable())
143bool BufferedAsyncSerial::connect()
146 struct android_app* androidApp = (
struct android_app*)SCgetExtra(
"this_inst");
147 androidApp->activity->vm->AttachCurrentThread(&env, NULL);
150 jobject oActivity = androidApp->activity->clazz;
151 jclass cActivity = env->GetObjectClass(oActivity);
154 jobject scolexternal_object = 0;
155 jclass scolexternal_clazz = 0;
156 jmethodID jHaveBluetooth = 0;
158 jfieldID scolexternal_fieldID = env->GetFieldID(cActivity,
"mScolExternal",
"Lorg/imaginer/scol/ScolExternal;");
159 if (scolexternal_fieldID)
160 scolexternal_object = env->GetObjectField(oActivity, scolexternal_fieldID);
161 if (scolexternal_object)
162 scolexternal_clazz = env->GetObjectClass(scolexternal_object);
163 if (scolexternal_clazz)
164 jHaveBluetooth = env->GetMethodID(scolexternal_clazz,
"haveBluetooth",
"()Z");
169 env->DeleteLocalRef(cActivity);
170 androidApp->activity->vm->DetachCurrentThread();
173 bool havebt = (bool)env->CallBooleanMethod(scolexternal_object, jHaveBluetooth);
177 if (env->ExceptionCheck())
179 env->ExceptionClear();
180 MMechostr(MSKRUNTIME,
"Android bluetooth exception : Check android.permission.BLUETOOTH\n");
184 env->DeleteLocalRef(scolexternal_object);
185 env->DeleteLocalRef(cActivity);
186 androidApp->activity->vm->DetachCurrentThread();
189 jmethodID jConnectBluetooth = env->GetMethodID(scolexternal_clazz,
"connectBluetooth",
"(Ljava/lang/String;)Z");
191 if (!jConnectBluetooth)
194 env->DeleteLocalRef(scolexternal_clazz);
195 env->DeleteLocalRef(scolexternal_object);
196 env->DeleteLocalRef(cActivity);
197 androidApp->activity->vm->DetachCurrentThread();
201 jstring address = env->NewStringUTF(mPort.c_str());
202 mConnected = (bool)env->CallBooleanMethod(scolexternal_object, jConnectBluetooth, address);
204 if (env->ExceptionCheck())
206 env->ExceptionClear();
207 MMechostr(MSKRUNTIME,
"Android bluetooth exception : Could not connect to device.\n");
211 env->DeleteLocalRef(address);
212 env->DeleteLocalRef(scolexternal_clazz);
213 env->DeleteLocalRef(scolexternal_object);
214 env->DeleteLocalRef(cActivity);
217 androidApp->activity->vm->DetachCurrentThread();
221void BufferedAsyncSerial::disconnect()
224 struct android_app* androidApp = (
struct android_app*)SCgetExtra(
"this_inst");
225 androidApp->activity->vm->AttachCurrentThread(&env, NULL);
228 jobject oActivity = androidApp->activity->clazz;
229 jclass cActivity = env->GetObjectClass(oActivity);
232 jobject scolexternal_object = 0;
233 jclass scolexternal_clazz = 0;
234 jmethodID jDisconnectBluetooth = 0;
236 jfieldID scolexternal_fieldID = env->GetFieldID(cActivity,
"mScolExternal",
"Lorg/imaginer/scol/ScolExternal;");
237 if (scolexternal_fieldID)
238 scolexternal_object = env->GetObjectField(oActivity, scolexternal_fieldID);
239 if (scolexternal_object)
240 scolexternal_clazz = env->GetObjectClass(scolexternal_object);
241 if (scolexternal_clazz)
242 jDisconnectBluetooth = env->GetMethodID(scolexternal_clazz,
"disconnectBluetooth",
"()V");
243 if (jDisconnectBluetooth)
244 env->CallVoidMethod(scolexternal_object, jDisconnectBluetooth);
246 if (env->ExceptionCheck())
248 env->ExceptionClear();
249 MMechostr(MSKRUNTIME,
"Android bluetooth exception : could not disconnect from device.\n");
253 env->DeleteLocalRef(scolexternal_clazz);
254 env->DeleteLocalRef(scolexternal_object);
255 env->DeleteLocalRef(cActivity);
258 androidApp->activity->vm->DetachCurrentThread();
261void BufferedAsyncSerial::cbThread()
270 boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
274 boost::this_thread::sleep_for(boost::chrono::milliseconds(16));
278void BufferedAsyncSerial::readData()
281 struct android_app* androidApp = (
struct android_app*)SCgetExtra(
"this_inst");
282 androidApp->activity->vm->AttachCurrentThread(&env, NULL);
285 jobject oActivity = androidApp->activity->clazz;
286 jclass cActivity = env->GetObjectClass(oActivity);
289 jobject scolexternal_object = 0;
290 jclass scolexternal_clazz = 0;
291 jmethodID jReadBluetooth = 0;
293 jfieldID scolexternal_fieldID = env->GetFieldID(cActivity,
"mScolExternal",
"Lorg/imaginer/scol/ScolExternal;");
294 if (scolexternal_fieldID)
295 scolexternal_object = env->GetObjectField(oActivity, scolexternal_fieldID);
296 if (scolexternal_object)
297 scolexternal_clazz = env->GetObjectClass(scolexternal_object);
298 if (scolexternal_clazz)
299 jReadBluetooth = env->GetMethodID(scolexternal_clazz,
"getBluetoothData",
"()[B");
304 env->DeleteLocalRef(cActivity);
305 androidApp->activity->vm->DetachCurrentThread();
309 jbyteArray jarray = (jbyteArray)env->CallObjectMethod(scolexternal_object, jReadBluetooth);
313 jsize lenght = env->GetArrayLength(jarray);
314 jbyte* data = env->GetByteArrayElements(jarray, &isCopy);
315 if (env->ExceptionCheck())
317 env->ExceptionClear();
318 env->DeleteLocalRef(jarray);
319 env->DeleteLocalRef(scolexternal_object);
320 env->DeleteLocalRef(cActivity);
321 androidApp->activity->vm->DetachCurrentThread();
327 char* sdata = (
char*)malloc(lenght);
328 memcpy(sdata, (
char*)data, lenght);
331 std::string* buffer =
new std::string(sdata, lenght);
332 OBJpostEvent(SERIAL_READ_CB, SCOL_PTR
this, SCOL_PTR buffer);
338 env->ReleaseByteArrayElements(jarray, data, 0);
340 if (env->ExceptionCheck())
342 env->ExceptionClear();
343 env->DeleteLocalRef(jarray);
344 env->DeleteLocalRef(scolexternal_object);
345 env->DeleteLocalRef(cActivity);
346 androidApp->activity->vm->DetachCurrentThread();
349 env->DeleteLocalRef(jarray);
353 env->DeleteLocalRef(scolexternal_object);
354 env->DeleteLocalRef(cActivity);
357 androidApp->activity->vm->DetachCurrentThread();
363 struct android_app* androidApp = (
struct android_app*)SCgetExtra(
"this_inst");
364 androidApp->activity->vm->AttachCurrentThread(&env, NULL);
367 jobject oActivity = androidApp->activity->clazz;
368 jclass cActivity = env->GetObjectClass(oActivity);
371 jobject scolexternal_object = 0;
372 jclass scolexternal_clazz = 0;
373 jmethodID jWriteBluetooth = 0;
375 jfieldID scolexternal_fieldID = env->GetFieldID(cActivity,
"mScolExternal",
"Lorg/imaginer/scol/ScolExternal;");
376 if (scolexternal_fieldID)
377 scolexternal_object = env->GetObjectField(oActivity, scolexternal_fieldID);
378 if (scolexternal_object)
379 scolexternal_clazz = env->GetObjectClass(scolexternal_object);
380 if (scolexternal_clazz)
381 jWriteBluetooth = env->GetMethodID(scolexternal_clazz,
"writeBluetoothData",
"([B)Z");
383 if (!jWriteBluetooth)
386 env->DeleteLocalRef(cActivity);
387 androidApp->activity->vm->DetachCurrentThread();
391 char* sdata = (
char*)malloc(s.size());
392 memcpy(sdata, s.data(), s.size());
393 int dataSize = s.size();
395 jbyteArray jdata = env->NewByteArray(dataSize);
396 env->SetByteArrayRegion(jdata, 0, dataSize, (jbyte *)sdata);
398 bool result = (bool)env->CallBooleanMethod(scolexternal_object, jWriteBluetooth, jdata);
402 env->ReleaseByteArrayElements(jdata, (jbyte *)sdata, JNI_COMMIT);
404 if (env->ExceptionCheck())
406 env->ExceptionClear();
407 env->DeleteLocalRef(jdata);
408 env->DeleteLocalRef(scolexternal_object);
409 env->DeleteLocalRef(cActivity);
415 androidApp->activity->vm->DetachCurrentThread();
421 env->DeleteLocalRef(jdata);
422 env->DeleteLocalRef(scolexternal_object);
423 env->DeleteLocalRef(cActivity);
431 androidApp->activity->vm->DetachCurrentThread();
void writeString(const std::string &s)
std::string readStringUntil(const std::string delim="\n")
std::vector< char > read()