sl_async_transceiver.cpp
Go to the documentation of this file.
1 /*
2  * Slamtec LIDAR SDK
3  *
4  * Copyright (c) 2014 - 2023 Shanghai Slamtec Co., Ltd.
5  * http://www.slamtec.com
6  *
7  */
8  /*
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 
34 
35 #include "sdkcommon.h"
36 #include "hal/abs_rxtx.h"
37 #include "hal/thread.h"
38 #include "hal/types.h"
39 #include "hal/assert.h"
40 #include "hal/locker.h"
41 #include "hal/socket.h"
42 #include "hal/event.h"
43 
44 #include "sl_async_transceiver.h"
45 
46 
47 
48 namespace sl { namespace internal {
49 
50 
51 
52 
54  : len(0)
55  , cmd(0)
56  , data(NULL)
57  , _databufsize(0)
58  , _usingOutterData(false)
59 {
61 }
62 
63 ProtocolMessage::ProtocolMessage(_u8 cmd, const void* buffer, size_t size)
64  : len(size)
65  , cmd(cmd)
66  , data(NULL)
67  , _databufsize(0)
68  , _usingOutterData(false)
69 {
71  if (buffer)
72  {
73  memcpy(data, buffer, size);
74  }
75 }
76 
78  : len(srcMsg.len)
79  , cmd(srcMsg.cmd)
80  , data(NULL)
81  , _databufsize(0)
82  , _usingOutterData(false)
83 {
84  _changeBufSize( true );
85  if (srcMsg.data && len)
86  {
87  memcpy(data, srcMsg.data, len);
88  }
89 }
90 
92 {
93  this->cleanData();
94 }
95 
97 {
98  this->cleanData();
99 
100 
101  this->len = srcMessage.len;
102  this->cmd = srcMessage.cmd;
103 
104  _changeBufSize( true );
105  if (srcMessage.data && len)
106  {
107  memcpy(data, srcMessage.data, len);
108  }
109 
110  return *this;
111 }
112 
113 void ProtocolMessage::setDataBuf(_u8 *buffer, size_t size)
114 {
115  this->cleanData();
116 
117  len = size;
118  data = buffer;
119  _databufsize = size;
120  _usingOutterData = true;
121 }
122 
123 void ProtocolMessage::fillData(const void * buffer, size_t size)
124 {
125  len = size;
126  _changeBufSize();
127  if (buffer)
128  memcpy(data, buffer, size);
129 }
130 
132 {
133  if (data)
134  {
135  if (!_usingOutterData)
136  {
137  delete [] data;
138  }
139  data = NULL;
140  len = 1;
141  _databufsize = 0;
142  }
143 }
144 
145 void ProtocolMessage::_changeBufSize( bool force_compact)
146 {
147  size_t actual_size = getPayloadSize();
148 
149  size_t new_buf_size = actual_size;
150 
151 
152  if (!_usingOutterData)
153  {
154  // nothing to do
155  if ( new_buf_size == _databufsize ) return;
156 
157  if ( new_buf_size < _databufsize){
158 
159  if ( (_databufsize >> 1) < new_buf_size)
160  {
161  // reuse the current buffer
162  if (!force_compact) return;
163  }else
164  {
165  // the current buffer size is much bigger, we need to release it to save memory
166  }
167  }
168  }
169 
170  // we need to change the buffer
171  cleanData();
172  // the cleanData() will reset the length info, so we need to restore it
173  len = actual_size;
174  data = new _u8[new_buf_size];
175  _databufsize = new_buf_size;
176 }
177 
178 
180  : _bindedChannel(NULL)
181  , _codec(codec)
182  , _isWorking(false)
183  , _workingFlag(0)
184 {
185 
186 }
187 
189 {
190  unbindAndClose();
191 }
192 
194 {
195  if (!channel) return RESULT_INVALID_DATA;
196 
197  unbindAndClose();
198  u_result ans = RESULT_OK;
199  do
200  {
202 
203  // try to open the channel ...
205 
206  if (!channel->open()) {
208  break;
209  }
210 
211 
212  // force a flush to clear any pending data
213  channel->flush();
214 
215  _dataEvt.set(false);
216 
217  _isWorking = true;
218  _workingFlag = 0;
219  _bindedChannel = channel;
220 
221 
224 
225 
226 
227 
228  } while (0);
229 
230  return ans;
231 }
232 
234 {
236  if (!_isWorking) return;
237 
238  assert(_bindedChannel);
239 
240 
241  _isWorking = false;
242  _dataEvt.set(); // set signal to wake up threads
243 
245  _rxThread.join();
246 
247 
249 
250  _bindedChannel = NULL;
251 
252 
253  for (std::list< Buffer* >::iterator itr = _rxQueue.begin(); itr != _rxQueue.end(); ++itr)
254  {
255  delete [] *itr;
256  }
257  _rxQueue.clear();
258 
259 }
260 
262 {
263  assert(msg);
264 
266 
268 
269  size_t requiredBufferSize = _codec.estimateLength(msg);
270 
271  if (requiredBufferSize == 0) {
272  // nothing to send
273  return RESULT_OK;
274  }
275 
276  u_result ans = RESULT_OK;
277 
278  _u8* txBuffer = new _u8[requiredBufferSize];
279 
280  do {
281 
282  if (!txBuffer) {
284  }
285 
286  _codec.onEncodeData(msg, txBuffer, &requiredBufferSize);
287 
288  int txSize = _bindedChannel->write(txBuffer, requiredBufferSize);
289 
290  if (txSize < 0) ans = RESULT_OPERATION_FAIL;
291 
292  } while (0);
293 
294 
295  delete[] txBuffer;
296  return ans;
297 }
298 
300 {
301  assert(_bindedChannel);
302 
304 
306  size_t hintedSize = 0;
307  while (_isWorking)
308  {
309  result = _bindedChannel->waitForDataExt(hintedSize, 1000);
310 
311  if (IS_FAIL(result))
312  {
313  // timeout is allowed
315  continue;
316  }
317  if (_isWorking) {
320  break;
321  }
322  }
323 
324  // no data in buffer, sleep and wait for the next round
325  if (!hintedSize)
326  {
327  continue;
328  }
329 
330 
331  Buffer* decodeBuffer = new Buffer();
332 
333  decodeBuffer->data = new _u8[hintedSize];
334 
335  decodeBuffer->size = _bindedChannel->read(decodeBuffer->data, hintedSize);
336 #ifdef _DEBUG_DUMP_PACKET
337  printf("Revc: %d\n", decodeBuffer->size);
338 #endif
339 
340  if (!decodeBuffer->size) {
341  delete decodeBuffer;
342 
343 
346  break;
347  }
348 
349  assert(hintedSize >= decodeBuffer->size);
350 
351 
352 #ifdef _DEBUG_DUMP_PACKET
353  printf("=== Dump RX Packet, size = %d ===\n", decodeBuffer->size);
354  for (int pos = 0; pos < decodeBuffer->size; pos++)
355  {
356  printf("%02x ", decodeBuffer->data[pos]);
357  }
358  printf("\n=== END ===\n");
359 #endif
360 
361  _rxLocker.lock();
362  _rxQueue.push_back(decodeBuffer);
363  _dataEvt.set();
364  _rxLocker.unlock();
365 
366 
367  }
369  return RESULT_OK;
370 }
371 
373 {
374 
375  assert(_bindedChannel);
378 
379 
380  while (_isWorking)
381  {
382  _rxLocker.lock();
383 
384  if (_rxQueue.empty())
385  {
386  _rxLocker.unlock();
387 
388  if (_dataEvt.wait(1000))
389  continue;
390 
391  _rxLocker.lock();
392  }
393  assert(!_rxQueue.empty());
394 
395  Buffer * bufferToDecode = _rxQueue.front();
396  _rxQueue.pop_front();
397 
398  _rxLocker.unlock();
399 
400  //cout<<"decoding "<< bufferToDecode->size <<" bytes of data"<<endl;
401  _codec.onDecodeData(bufferToDecode->data, bufferToDecode->size);
402 
403 
404  delete bufferToDecode;
405  }
406 
407  return RESULT_OK;
408 
409 }
410 
411 
412 }}
sl::internal::ProtocolMessage::ProtocolMessage
ProtocolMessage()
Definition: sl_async_transceiver.cpp:53
sdkcommon.h
u_result
uint32_t u_result
Definition: rptypes.h:100
sl::internal::AsyncTransceiver::openChannelAndBind
u_result openChannelAndBind(IChannel *channel)
Definition: sl_async_transceiver.cpp:193
sl::internal::IAsyncProtocolCodec::onChannelError
virtual void onChannelError(u_result errCode)
Definition: sl_async_transceiver.h:90
sl::internal::AsyncTransceiver::Buffer
Definition: sl_async_transceiver.h:149
sl::IChannel::close
virtual void close()=0
sl::internal::ProtocolMessage::getPayloadSize
size_t getPayloadSize() const
Definition: sl_async_transceiver.h:66
rp::hal::Thread::SetSelfPriority
static u_result SetSelfPriority(priority_val_t p)
Definition: linux/thread.hpp:64
rp::hal::Locker::unlock
void unlock()
Definition: locker.h:117
sl::internal::IAsyncProtocolCodec::onDecodeReset
virtual void onDecodeReset()
Definition: sl_async_transceiver.h:92
RESULT_INVALID_DATA
#define RESULT_INVALID_DATA
Definition: rptypes.h:105
types.h
sl::IChannel
Definition: sl_lidar_driver.h:171
sl::internal::AsyncTransceiver::_rxThread
rp::hal::Thread _rxThread
Definition: sl_async_transceiver.h:146
sl::internal::ProtocolMessage::cleanData
void cleanData()
Definition: sl_async_transceiver.cpp:131
sl::internal::AsyncTransceiver::_isWorking
bool _isWorking
Definition: sl_async_transceiver.h:143
sl::internal::ProtocolMessage::len
size_t len
Definition: sl_async_transceiver.h:44
sl::internal::AsyncTransceiver::_rxQueue
std::list< Buffer * > _rxQueue
Definition: sl_async_transceiver.h:163
RESULT_OK
#define RESULT_OK
Definition: rptypes.h:102
CLASS_THREAD
#define CLASS_THREAD(c, x)
Definition: thread.h:38
RESULT_INSUFFICIENT_MEMORY
#define RESULT_INSUFFICIENT_MEMORY
Definition: rptypes.h:111
assert.h
sl::internal::AsyncTransceiver::~AsyncTransceiver
~AsyncTransceiver()
Definition: sl_async_transceiver.cpp:188
sl::internal::IAsyncProtocolCodec::estimateLength
virtual size_t estimateLength(message_autoptr_t &message)=0
sl::internal::ProtocolMessage::data
_u8 * data
Definition: sl_async_transceiver.h:47
_u8
uint8_t _u8
Definition: rptypes.h:63
SL_RESULT_OK
#define SL_RESULT_OK
Definition: sl_types.h:71
IS_FAIL
#define IS_FAIL(x)
Definition: rptypes.h:114
sl::internal::AsyncTransceiver::_dataEvt
rp::hal::Event _dataEvt
Definition: sl_async_transceiver.h:137
sl::internal::ProtocolMessage::_changeBufSize
void _changeBufSize(bool force_compact=false)
Definition: sl_async_transceiver.cpp:145
size
sl_u8 size
Definition: sl_lidar_protocol.h:4
sl::IChannel::flush
virtual void flush()=0
sl::internal::AsyncTransceiver::AsyncTransceiver
AsyncTransceiver(IAsyncProtocolCodec &codec)
Definition: sl_async_transceiver.cpp:179
sl::internal::AsyncTransceiver::_proc_rxThread
sl_result _proc_rxThread()
Definition: sl_async_transceiver.cpp:299
locker.h
result
sl_u32 result
Definition: sl_lidar_cmd.h:3
sl::internal::ProtocolMessage
Definition: sl_async_transceiver.h:41
sl::internal::IAsyncProtocolCodec
Definition: sl_async_transceiver.h:85
RESULT_OPERATION_ABORTED
#define RESULT_OPERATION_ABORTED
Definition: types.h:98
sl::internal::AsyncTransceiver::WORKING_FLAG_ERROR
@ WORKING_FLAG_ERROR
Definition: sl_async_transceiver.h:109
sl::internal::ProtocolMessage::setDataBuf
void setDataBuf(_u8 *buffer, size_t size)
Definition: sl_async_transceiver.cpp:113
sl::internal::AsyncTransceiver::_opLocker
rp::hal::Locker _opLocker
Definition: sl_async_transceiver.h:135
sl::internal::IAsyncProtocolCodec::onDecodeData
virtual void onDecodeData(const void *buffer, size_t size)=0
sl::IChannel::waitForDataExt
virtual sl_result waitForDataExt(size_t &size_hint, sl_u32 timeoutInMs=1000)=0
rp::hal::Thread::PRIORITY_HIGH
@ PRIORITY_HIGH
Definition: thread.h:49
RESULT_OPERATION_TIMEOUT
#define RESULT_OPERATION_TIMEOUT
Definition: rptypes.h:107
rp::hal::AutoLocker
Definition: locker.h:188
sl
Definition: sl_crc.h:38
sl::internal::AsyncTransceiver::_proc_decoderThread
sl_result _proc_decoderThread()
Definition: sl_async_transceiver.cpp:372
rp::hal::Event::set
void set(bool isSignal=true)
Definition: event.h:78
sl::internal::AsyncTransceiver::_bindedChannel
IChannel * _bindedChannel
Definition: sl_async_transceiver.h:139
sl::internal::IAsyncProtocolCodec::onEncodeData
virtual void onEncodeData(message_autoptr_t &message, _u8 *txbuffer, size_t *size)=0
event.h
sl::internal::AsyncTransceiver
Definition: sl_async_transceiver.h:101
sl::internal::ProtocolMessage::operator=
ProtocolMessage & operator=(const ProtocolMessage &srcMessage)
Definition: sl_async_transceiver.cpp:96
sl::IChannel::read
virtual int read(void *buffer, size_t size)=0
rp::hal::Locker::lock
Locker::LOCK_STATUS lock(unsigned long timeout=0xFFFFFFFF)
Definition: locker.h:60
sl::internal::message_autoptr_t
std::shared_ptr< ProtocolMessage > message_autoptr_t
Definition: sl_async_transceiver.h:82
sl::internal::ProtocolMessage::cmd
_u8 cmd
Definition: sl_async_transceiver.h:45
abs_rxtx.h
sl::internal::AsyncTransceiver::_decoderThread
rp::hal::Thread _decoderThread
Definition: sl_async_transceiver.h:147
sl::internal::AsyncTransceiver::_rxLocker
rp::hal::Locker _rxLocker
Definition: sl_async_transceiver.h:136
sl::internal::AsyncTransceiver::sendMessage
u_result sendMessage(message_autoptr_t &msg)
Definition: sl_async_transceiver.cpp:261
sl::internal::AsyncTransceiver::Buffer::size
size_t size
Definition: sl_async_transceiver.h:150
sl::internal::AsyncTransceiver::Buffer::data
_u8 * data
Definition: sl_async_transceiver.h:151
sl::internal::ProtocolMessage::fillData
void fillData(const void *buffer, size_t size)
Definition: sl_async_transceiver.cpp:123
RESULT_OPERATION_NOT_SUPPORT
#define RESULT_OPERATION_NOT_SUPPORT
Definition: rptypes.h:109
sl::internal::ProtocolMessage::_databufsize
size_t _databufsize
Definition: sl_async_transceiver.h:48
RESULT_OPERATION_FAIL
#define RESULT_OPERATION_FAIL
Definition: rptypes.h:106
sl::IChannel::open
virtual bool open()=0
sl::internal::AsyncTransceiver::_codec
IAsyncProtocolCodec & _codec
Definition: sl_async_transceiver.h:140
sl::IChannel::write
virtual int write(const void *data, size_t size)=0
sl_async_transceiver.h
sl::internal::AsyncTransceiver::WORKING_FLAG_RX_DISABLED
@ WORKING_FLAG_RX_DISABLED
Definition: sl_async_transceiver.h:106
socket.h
sl_result
uint32_t sl_result
Definition: sl_types.h:69
sl::Result
Definition: sl_lidar_driver.h:92
sl::internal::AsyncTransceiver::_workingFlag
_u32 _workingFlag
Definition: sl_async_transceiver.h:144
data
sl_u8 data[0]
Definition: sl_lidar_protocol.h:5
sl::internal::ProtocolMessage::~ProtocolMessage
virtual ~ProtocolMessage()
Definition: sl_async_transceiver.cpp:91
thread.h
sl::internal::AsyncTransceiver::unbindAndClose
void unbindAndClose()
Definition: sl_async_transceiver.cpp:233
rp::hal::Thread::join
u_result join(unsigned long timeout=-1)
Definition: linux/thread.hpp:176
sl::internal::ProtocolMessage::_usingOutterData
bool _usingOutterData
Definition: sl_async_transceiver.h:77
rp::hal::Event::wait
unsigned long wait(unsigned long timeout=0xFFFFFFFF)
Definition: event.h:106


rplidar_ros
Author(s):
autogenerated on Fri Aug 2 2024 08:42:14