00001
00050 #ifdef _MSC_VER
00051 #pragma warning(disable: 4996)
00052 #pragma warning(disable: 4267)
00053 #pragma warning(disable: 4101) // C4101: "e" : Unreferenzierte lokale Variable
00054 #define _WIN32_WINNT 0x0501
00055
00056 #endif
00057
00058 #include <sick_scan/sick_scan_common_tcp.h>
00059 #include <sick_scan/tcp/colaa.hpp>
00060 #include <sick_scan/tcp/colab.hpp>
00061
00062 #include <boost/asio.hpp>
00063 #include <boost/lambda/lambda.hpp>
00064 #include <algorithm>
00065 #include <iterator>
00066 #include <boost/lexical_cast.hpp>
00067 #include <vector>
00068 #include <sick_scan/sick_generic_radar.h>
00069
00070 #ifdef _MSC_VER
00071 #include "sick_scan/rosconsole_simu.hpp"
00072 #endif
00073
00074 std::vector<unsigned char> exampleData(65536);
00075 std::vector<unsigned char> receivedData(65536);
00076 static long receivedDataLen = 0;
00077 static int getDiagnosticErrorCode()
00078 {
00079 #ifdef _MSC_VER
00080 #undef ERROR
00081 return(2);
00082 #else
00083 return(diagnostic_msgs::DiagnosticStatus::ERROR);
00084 #endif
00085 }
00086 namespace sick_scan
00087 {
00088 bool emulateReply(UINT8*requestData, int requestLen, std::vector<unsigned char>* replyVector)
00089 {
00090 std::string request;
00091 std::string reply;
00092 std::vector<std::string> keyWordList;
00093 std::vector<std::string> answerList;
00094
00095 keyWordList.push_back("sMN SetAccessMode");
00096 answerList.push_back("sAN SetAccessMode 1");
00097
00098 keyWordList.push_back("sWN EIHstCola");
00099 answerList.push_back("sWA EIHstCola");
00100
00101 keyWordList.push_back("sRN FirmwareVersion");
00102 answerList.push_back("sRA FirmwareVersion 8 1.0.0.0R");
00103
00104 keyWordList.push_back("sRN OrdNum");
00105 answerList.push_back("sRA OrdNum 7 1234567");
00106
00107 keyWordList.push_back("sWN TransmitTargets 1");
00108 answerList.push_back("sWA TransmitTargets");
00109
00110 keyWordList.push_back("sWN TransmitObjects 1");
00111 answerList.push_back("sWA TransmitObjects");
00112
00113 keyWordList.push_back("sWN TCTrackingMode 0");
00114 answerList.push_back("sWA TCTrackingMode");
00115
00116 keyWordList.push_back("sRN SCdevicestate");
00117 answerList.push_back("sRA SCdevicestate 1");
00118
00119 keyWordList.push_back("sRN DItype");
00120 answerList.push_back("sRA DItype D RMS3xx-xxxxxx");
00121
00122 keyWordList.push_back("sRN ODoprh");
00123 answerList.push_back("sRA ODoprh 451");
00124
00125 keyWordList.push_back("sMN mSCloadappdef");
00126 answerList.push_back("sAN mSCloadappdef");
00127
00128
00129 keyWordList.push_back("sRN SerialNumber");
00130 answerList.push_back("sRA SerialNumber 8 18020073");
00131
00132 keyWordList.push_back("sMN Run");
00133 answerList.push_back("sAN Run 1s");
00134
00135 keyWordList.push_back("sRN ODpwrc");
00136 answerList.push_back("sRA ODpwrc 20");
00137
00138 keyWordList.push_back("sRN LocationName");
00139 answerList.push_back("sRA LocationName B not defined");
00140
00141 keyWordList.push_back("sEN LMDradardata 1");
00142 answerList.push_back("sEA LMDradardata 1");
00143
00144 for (int i = 0; i < requestLen; i++)
00145 {
00146 request += (char)requestData[i];
00147 }
00148 for (int i = 0; i < keyWordList.size(); i++)
00149 {
00150 if (request.find(keyWordList[i]) != std::string::npos)
00151 {
00152 reply = (char)0x02;
00153 reply += answerList[i];
00154 reply += (char)0x03;
00155 }
00156 }
00157
00158 replyVector->clear();
00159 for (int i = 0; i < reply.length(); i++)
00160 {
00161 replyVector->push_back((unsigned char)reply[i]);
00162 }
00163
00164
00165 return(true);
00166 }
00167
00168
00169
00170 SickScanCommonTcp::SickScanCommonTcp(const std::string &hostname, const std::string &port, int &timelimit, SickGenericParser* parser, char cola_dialect_id)
00171 :
00172 SickScanCommon(parser),
00173 socket_(io_service_),
00174 deadline_(io_service_),
00175 hostname_(hostname),
00176 port_(port),
00177 timelimit_(timelimit)
00178 {
00179
00180 setEmulSensor(false);
00181 if ((cola_dialect_id == 'a') || (cola_dialect_id == 'A'))
00182 {
00183 this->setProtocolType(CoLa_A);
00184 }
00185
00186 if ((cola_dialect_id == 'b') || (cola_dialect_id == 'B'))
00187 {
00188 this->setProtocolType(CoLa_B);
00189 }
00190
00191 assert(this->getProtocolType() != CoLa_Unknown);
00192
00193 m_numberOfBytesInReceiveBuffer = 0;
00194 m_alreadyReceivedBytes = 0;
00195 this->setReplyMode(0);
00196
00197
00198
00199
00200
00201 deadline_.expires_at(boost::posix_time::pos_infin);
00202 checkDeadline();
00203
00204 }
00205
00206 SickScanCommonTcp::~SickScanCommonTcp()
00207 {
00208
00209 close_device();
00210 }
00211
00212 using boost::asio::ip::tcp;
00213 using boost::lambda::var;
00214 using boost::lambda::_1;
00215
00216
00217 void SickScanCommonTcp::disconnectFunction()
00218 {
00219
00220 }
00221
00222 void SickScanCommonTcp::disconnectFunctionS(void *obj)
00223 {
00224 if (obj != NULL)
00225 {
00226 ((SickScanCommonTcp *)(obj))->disconnectFunction();
00227 }
00228 }
00229
00230 void SickScanCommonTcp::readCallbackFunctionS(void* obj, UINT8* buffer, UINT32& numOfBytes)
00231 {
00232 ((SickScanCommonTcp*)obj)->readCallbackFunction(buffer, numOfBytes);
00233 }
00234
00235
00236 void SickScanCommonTcp::setReplyMode(int _mode)
00237 {
00238 m_replyMode = _mode;
00239 }
00240 int SickScanCommonTcp::getReplyMode()
00241 {
00242 return(m_replyMode);
00243 }
00244
00245 #if 0
00246 void SickScanCommonTcp::setProtocolType(char cola_dialect_id)
00247 {
00248 if ((cola_dialect_id == 'a') || (cola_dialect_id == 'A'))
00249 {
00250 this->m_protocol = CoLa_A;
00251 }
00252 else
00253 {
00254 this->m_protocol = CoLa_B;
00255 }
00256 }
00257 #endif
00258
00263 void SickScanCommonTcp::setEmulSensor(bool _emulFlag)
00264 {
00265 m_emulSensor = _emulFlag;
00266 }
00267
00273 bool SickScanCommonTcp::getEmulSensor()
00274 {
00275 return(m_emulSensor);
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285 SopasEventMessage SickScanCommonTcp::findFrameInReceiveBuffer()
00286 {
00287 UINT32 frameLen = 0;
00288 UINT32 i;
00289
00290
00291 if (getProtocolType() == CoLa_A)
00292 {
00293
00294
00295
00296
00297 if (m_receiveBuffer[0] != 0x02)
00298 {
00299
00300 for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
00301 {
00302 if (m_receiveBuffer[i] == 0x02)
00303 {
00304 break;
00305 }
00306 }
00307
00308
00309 if (i >= m_numberOfBytesInReceiveBuffer)
00310 {
00311
00312 m_numberOfBytesInReceiveBuffer = 0;
00313 return SopasEventMessage();
00314 }
00315
00316
00317 UINT32 newLen = m_numberOfBytesInReceiveBuffer - i;
00318 memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), newLen);
00319 m_numberOfBytesInReceiveBuffer = newLen;
00320 }
00321
00322
00323 for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
00324 {
00325 if (m_receiveBuffer[i] == 0x03)
00326 {
00327 break;
00328 }
00329 }
00330
00331
00332 if (i >= m_numberOfBytesInReceiveBuffer)
00333 {
00334
00335 return SopasEventMessage();
00336 }
00337
00338
00339 frameLen = i + 1;
00340
00341 return SopasEventMessage(m_receiveBuffer, CoLa_A, frameLen);
00342 }
00343 else if (getProtocolType() == CoLa_B)
00344 {
00345 UINT32 magicWord;
00346 UINT32 payloadlength;
00347
00348 if (m_numberOfBytesInReceiveBuffer < 4)
00349 {
00350 return SopasEventMessage();
00351 }
00352 UINT16 pos = 0;
00353 magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00354 if (magicWord != 0x02020202)
00355 {
00356
00357 for (i = 1; i <= m_numberOfBytesInReceiveBuffer - 4; i++)
00358 {
00359 pos = i;
00360 magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00361 if (magicWord == 0x02020202)
00362 {
00363
00364 break;
00365 }
00366 }
00367
00368
00369 if (i > m_numberOfBytesInReceiveBuffer - 4)
00370 {
00371
00372 m_numberOfBytesInReceiveBuffer = 0;
00373 return SopasEventMessage();
00374 }
00375 else
00376 {
00377
00378 UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - i;
00379 memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), bytesToMove);
00380 m_numberOfBytesInReceiveBuffer = bytesToMove;
00381 }
00382 }
00383
00384
00385 if (m_numberOfBytesInReceiveBuffer < 9)
00386 {
00387
00388 printInfoMessage("SickScanCommonNw::findFrameInReceiveBuffer: Frame cannot be decoded yet, only " +
00389 ::toString(m_numberOfBytesInReceiveBuffer) + " bytes in the buffer.", m_beVerbose);
00390 return SopasEventMessage();
00391 }
00392
00393
00394 pos = 4;
00395 payloadlength = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00396 printInfoMessage("SickScanCommonNw::findFrameInReceiveBuffer: Decoded payload length is " + ::toString(payloadlength) + " bytes.", m_beVerbose);
00397
00398
00399 if (payloadlength > (sizeof(m_receiveBuffer) - 9))
00400 {
00401
00402 printWarning("SickScanCommonNw::findFrameInReceiveBuffer: Frame too big for receive buffer. Frame discarded with length:"
00403 + ::toString(payloadlength) + ".");
00404 m_numberOfBytesInReceiveBuffer = 0;
00405 return SopasEventMessage();
00406 }
00407 if ((payloadlength + 9) > m_numberOfBytesInReceiveBuffer)
00408 {
00409
00410 printInfoMessage("SickScanCommonNw::findFrameInReceiveBuffer: Frame not complete yet. Waiting for the rest of it (" +
00411 ::toString(payloadlength + 9 - m_numberOfBytesInReceiveBuffer) + " bytes missing).", m_beVerbose);
00412 return SopasEventMessage();
00413 }
00414
00415
00416 frameLen = payloadlength + 9;
00417
00418
00419
00420
00421 UINT8 temp = 0;
00422 UINT8 temp_xor = 0;
00423 UINT8 checkSum;
00424
00425
00426 pos = frameLen - 1;
00427 checkSum = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
00428
00429
00430 for (UINT16 i = 8; i < (frameLen - 1); i++)
00431 {
00432 pos = i;
00433 temp = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
00434 temp_xor = temp_xor ^ temp;
00435 }
00436
00437
00438 if (temp_xor != checkSum)
00439 {
00440 printWarning("SickScanCommonNw::findFrameInReceiveBuffer: Wrong checksum, Frame discarded.");
00441 m_numberOfBytesInReceiveBuffer = 0;
00442 return SopasEventMessage();
00443 }
00444
00445 return SopasEventMessage(m_receiveBuffer, CoLa_B, frameLen);
00446 }
00447
00448
00449 return SopasEventMessage();
00450 }
00451
00452
00453
00459 void SickScanCommonTcp::processFrame(ros::Time timeStamp, SopasEventMessage& frame)
00460 {
00461
00462 if (getProtocolType() == CoLa_A)
00463 {
00464 printInfoMessage("SickScanCommonNw::processFrame: Calling processFrame_CoLa_A() with " + ::toString(frame.size()) + " bytes.", m_beVerbose);
00465
00466 }
00467 else if (getProtocolType() == CoLa_B)
00468 {
00469 printInfoMessage("SickScanCommonNw::processFrame: Calling processFrame_CoLa_B() with " + ::toString(frame.size()) + " bytes.", m_beVerbose);
00470
00471 }
00472
00473
00474
00475 DatagramWithTimeStamp dataGramWidthTimeStamp(timeStamp, std::vector<unsigned char>(frame.getRawData(), frame.getRawData() + frame.size()));
00476
00477 recvQueue.push(dataGramWidthTimeStamp);
00478 }
00479
00480 void SickScanCommonTcp::readCallbackFunction(UINT8* buffer, UINT32& numOfBytes)
00481 {
00482 ros::Time rcvTimeStamp = ros::Time::now();
00483 bool beVerboseHere = false;
00484 printInfoMessage("SickScanCommonNw::readCallbackFunction(): Called with " + toString(numOfBytes) + " available bytes.", beVerboseHere);
00485
00486 ScopedLock lock(&m_receiveDataMutex);
00487 UINT32 remainingSpace = sizeof(m_receiveBuffer) - m_numberOfBytesInReceiveBuffer;
00488 UINT32 bytesToBeTransferred = numOfBytes;
00489 if (remainingSpace < numOfBytes)
00490 {
00491 bytesToBeTransferred = remainingSpace;
00492
00493
00494 }
00495 else
00496 {
00497
00498
00499 }
00500
00501 if (bytesToBeTransferred > 0)
00502 {
00503
00504 memcpy(&(m_receiveBuffer[m_numberOfBytesInReceiveBuffer]), buffer, bytesToBeTransferred);
00505 m_numberOfBytesInReceiveBuffer += bytesToBeTransferred;
00506
00507 UINT32 size = 0;
00508
00509 while (1)
00510 {
00511
00512 SopasEventMessage frame = findFrameInReceiveBuffer();
00513
00514 size = frame.size();
00515 if (size == 0)
00516 {
00517
00518
00519 printInfoMessage("SickScanCommonNw::readCallbackFunction(): No complete frame in input buffer, we are done.", beVerboseHere);
00520
00521
00522 break;
00523 }
00524 else
00525 {
00526
00527 printInfoMessage("SickScanCommonNw::readCallbackFunction(): Processing a frame of length " + ::toString(frame.size()) + " bytes.", beVerboseHere);
00528 processFrame(rcvTimeStamp, frame);
00529 UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - size;
00530 memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[size]), bytesToMove);
00531 m_numberOfBytesInReceiveBuffer = bytesToMove;
00532
00533 }
00534 }
00535 }
00536 else
00537 {
00538
00539
00540
00541 m_numberOfBytesInReceiveBuffer = 0;
00542 }
00543 }
00544
00545
00546 int SickScanCommonTcp::init_device()
00547 {
00548 int portInt;
00549 sscanf(port_.c_str(), "%d", &portInt);
00550 m_nw.init(hostname_, portInt, disconnectFunctionS, (void*)this);
00551 m_nw.setReadCallbackFunction(readCallbackFunctionS, (void*)this);
00552 if (this->getEmulSensor())
00553 {
00554 ROS_INFO("Sensor emulation is switched on - network traffic is switched off.");
00555 } else
00556 {
00557 m_nw.connect();
00558 }
00559 return ExitSuccess;
00560 }
00561
00562 int SickScanCommonTcp::close_device()
00563 {
00564 ROS_WARN("Disconnecting TCP-Connection.");
00565 m_nw.disconnect();
00566 return 0;
00567 }
00568
00569
00570 bool SickScanCommonTcp::stopScanData()
00571 {
00572 stop_scanner();
00573 return(true);
00574 }
00575
00576 void SickScanCommonTcp::handleRead(boost::system::error_code error, size_t bytes_transfered)
00577 {
00578 ec_ = error;
00579 bytes_transfered_ += bytes_transfered;
00580 }
00581
00582
00583 void SickScanCommonTcp::checkDeadline()
00584 {
00585 if (deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
00586 {
00587
00588
00589 socket_.close();
00590 deadline_.expires_at(boost::posix_time::pos_infin);
00591 }
00592
00593
00594 deadline_.async_wait(boost::bind(&SickScanCommonTcp::checkDeadline, this));
00595 }
00596
00597
00598 int SickScanCommonTcp::numberOfDatagramInInputFifo()
00599 {
00600 this->recvQueue.getNumberOfEntriesInQueue();
00601 }
00602
00603 int SickScanCommonTcp::readWithTimeout(size_t timeout_ms, char *buffer, int buffer_size, int *bytes_read, bool *exception_occured, bool isBinary)
00604 {
00605
00606 deadline_.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
00607 const char end_delim = static_cast<char>(0x03);
00608 int dataLen = 0;
00609 ec_ = boost::asio::error::would_block;
00610 bytes_transfered_ = 0;
00611
00612 size_t to_read;
00613
00614 int numBytes = 0;
00615
00616 int waitingTimeInMs = 1;
00617 int i;
00618 for (i = 0; i < timeout_ms; i += waitingTimeInMs)
00619 {
00620 if (false == this->recvQueue.isQueueEmpty())
00621 {
00622 break;
00623 }
00624 boost::this_thread::sleep(boost::posix_time::milliseconds(waitingTimeInMs));
00625 }
00626 if (i >= timeout_ms)
00627 {
00628 ROS_ERROR("no answer received after %zu ms. Maybe sopas mode is wrong.\n",timeout_ms);
00629 return(ExitError);
00630 }
00631 boost::condition_variable cond_;
00632 DatagramWithTimeStamp datagramWithTimeStamp = this->recvQueue.pop();
00633
00634 *bytes_read = datagramWithTimeStamp.datagram.size();
00635 memcpy(buffer, &(datagramWithTimeStamp.datagram[0]), datagramWithTimeStamp.datagram.size());
00636 return(ExitSuccess);
00637 }
00638
00642 int SickScanCommonTcp::sendSOPASCommand(const char* request, std::vector<unsigned char> * reply, int cmdLen)
00643 {
00644 #if 0
00645 if (!socket_.is_open()) {
00646 ROS_ERROR("sendSOPASCommand: socket not open");
00647 diagnostics_.broadcast(getDiagnosticErrorCode(), "sendSOPASCommand: socket not open.");
00648 return ExitError;
00649 }
00650 #endif
00651 int sLen = 0;
00652 int preambelCnt = 0;
00653 bool cmdIsBinary = false;
00654
00655 if (request != NULL)
00656 {
00657 sLen = cmdLen;
00658 preambelCnt = 0;
00659 if (sLen >= 4)
00660 {
00661 for (int i = 0; i < 4; i++) {
00662 if (request[i] == 0x02)
00663 {
00664 preambelCnt++;
00665 }
00666 }
00667 }
00668
00669 if (preambelCnt < 4) {
00670 cmdIsBinary = false;
00671 }
00672 else
00673 {
00674 cmdIsBinary = true;
00675 }
00676 int msgLen = 0;
00677 if (cmdIsBinary == false)
00678 {
00679 msgLen = strlen(request);
00680 }
00681 else
00682 {
00683 int dataLen = 0;
00684 for (int i = 4; i < 8; i++)
00685 {
00686 dataLen |= ((unsigned char)request[i] << (7 - i) * 8);
00687 }
00688 msgLen = 8 + dataLen + 1;
00689 }
00690 #if 1
00691 if (getEmulSensor())
00692 {
00693 emulateReply((UINT8*)request, msgLen, reply);
00694 }
00695 else
00696 {
00697 bool debugBinCmd = false;
00698 if (debugBinCmd)
00699 {
00700 printf("=== START HEX DUMP ===\n");
00701 for (int i = 0; i < msgLen; i++)
00702 {
00703 unsigned char *ptr = (UINT8*)request;
00704 printf("%02x ", ptr[i]);
00705 }
00706 printf("\n=== END HEX DUMP ===\n");
00707 }
00708 m_nw.sendCommandBuffer((UINT8*)request, msgLen);
00709 }
00710 #else
00711
00712
00713
00714
00715 try
00716 {
00717 boost::asio::write(socket_, boost::asio::buffer(request, msgLen));
00718 }
00719 catch (boost::system::system_error &e)
00720 {
00721 ROS_ERROR("write error for command: %s", request);
00722 diagnostics_.broadcast(getDiagnosticErrorCode(), "Write error for sendSOPASCommand.");
00723 return ExitError;
00724 }
00725 #endif
00726 }
00727
00728
00729 const int BUF_SIZE = 65536;
00730 char buffer[BUF_SIZE];
00731 int bytes_read;
00732
00733 if (getEmulSensor())
00734 {
00735
00736 }
00737 else
00738 {
00739 if (readWithTimeout(getReadTimeOutInMs(), buffer, BUF_SIZE, &bytes_read, 0, cmdIsBinary) == ExitError)
00740 {
00741 ROS_INFO_THROTTLE(1.0, "sendSOPASCommand: no full reply available for read after %d ms",getReadTimeOutInMs());
00742 diagnostics_.broadcast(getDiagnosticErrorCode(), "sendSOPASCommand: no full reply available for read after timeout.");
00743 return ExitError;
00744 }
00745
00746
00747 if (reply)
00748 {
00749 reply->resize(bytes_read);
00750
00751 std::copy(buffer, buffer + bytes_read, &(*reply)[0]);
00752 }
00753 }
00754 return ExitSuccess;
00755 }
00756
00757
00758 int SickScanCommonTcp::get_datagram(ros::Time &recvTimeStamp, unsigned char *receiveBuffer, int bufferSize, int *actual_length,
00759 bool isBinaryProtocol, int *numberOfRemainingFifoEntries)
00760 {
00761 if (NULL != numberOfRemainingFifoEntries)
00762 {
00763 *numberOfRemainingFifoEntries = 0;
00764 }
00765 this->setReplyMode(1);
00766
00767 if (this->getEmulSensor())
00768 {
00769
00770 ros::Time timeStamp = ros::Time::now();
00771 uint32_t nanoSec = timeStamp.nsec;
00772 double waitTime10Hz = 10.0 * (double)nanoSec / 1E9;
00773
00774 uint32_t waitTime = (int)waitTime10Hz ;
00775
00776 double waitTimeUntilNextTime10Hz = 1/10.0 * (1.0 - (waitTime10Hz - waitTime));
00777
00778 ros::Duration(waitTimeUntilNextTime10Hz).sleep();
00779 SickScanRadar radar(this);
00780 radar.setEmulation(true);
00781 radar.simulateAsciiDatagram(receiveBuffer, actual_length);
00782 recvTimeStamp = ros::Time::now();
00783 }
00784 else
00785 {
00786 const int maxWaitInMs = getReadTimeOutInMs();
00787 std::vector<unsigned char> dataBuffer;
00788 #if 1 // prepared for reconnect
00789 bool retVal = this->recvQueue.waitForIncomingObject(maxWaitInMs);
00790 if (retVal == false)
00791 {
00792 ROS_WARN("Timeout during waiting for new datagram");
00793 return ExitError;
00794 }
00795 else
00796 {
00797
00798
00799
00800 DatagramWithTimeStamp datagramWithTimeStamp = this->recvQueue.pop();
00801 if (NULL != numberOfRemainingFifoEntries)
00802 {
00803 *numberOfRemainingFifoEntries = this->recvQueue.getNumberOfEntriesInQueue();
00804 }
00805 recvTimeStamp = datagramWithTimeStamp.timeStamp;
00806 dataBuffer = datagramWithTimeStamp.datagram;
00807
00808 }
00809 #endif
00810
00811 long size = dataBuffer.size();
00812 memcpy(receiveBuffer, &(dataBuffer[0]), size);
00813 *actual_length = size;
00814 }
00815
00816 #if 0
00817 static int cnt = 0;
00818 char szFileName[255];
00819 sprintf(szFileName, "/tmp/dg%06d.bin", cnt++);
00820
00821 FILE *fout;
00822
00823 fout = fopen(szFileName, "wb");
00824 if (fout != NULL)
00825 {
00826 fwrite(receiveBuffer, size, 1, fout);
00827 fclose(fout);
00828 }
00829 #endif
00830 return ExitSuccess;
00831
00832 if (!socket_.is_open()) {
00833 ROS_ERROR("get_datagram: socket not open");
00834 diagnostics_.broadcast(getDiagnosticErrorCode(), "get_datagram: socket not open.");
00835 return ExitError;
00836 }
00837
00838
00839
00840
00841 std::vector<unsigned char> reply;
00842
00843
00844 size_t timeout = 30000;
00845 bool exception_occured = false;
00846
00847 char *buffer = reinterpret_cast<char *>(receiveBuffer);
00848
00849 if (readWithTimeout(timeout, buffer, bufferSize, actual_length, &exception_occured, isBinaryProtocol) != ExitSuccess)
00850 {
00851 ROS_ERROR_THROTTLE(1.0, "get_datagram: no data available for read after %zu ms", timeout);
00852 diagnostics_.broadcast(getDiagnosticErrorCode(), "get_datagram: no data available for read after timeout.");
00853
00854
00855 if (!socket_.is_open())
00856 {
00857 #ifdef _MSC_VER
00858 Sleep(1000);
00859 #else
00860 sleep(1);
00861 #endif
00862 ROS_INFO("Failure - attempting to reconnect");
00863 return init();
00864 }
00865
00866 return exception_occured ? ExitError : ExitSuccess;
00867 }
00868
00869 return ExitSuccess;
00870 }
00871
00872 }