00001
00022 #include "sick_scan/sick_scan_common_nw.h"
00023 #include "sick_scan/tcp/colaa.hpp"
00024 #include "sick_scan/tcp/colab.hpp"
00025 #include "sick_scan/tcp/BasicDatatypes.hpp"
00026 #include "sick_scan/tcp/tcp.hpp"
00027 #include <map>
00028
00029 #include "sick_scan/tcp/tcp.hpp"
00030 #include "sick_scan/tcp/errorhandler.hpp"
00031 #include "sick_scan/tcp/toolbox.hpp"
00032 #include "sick_scan/tcp/Mutex.hpp"
00033 #include <assert.h>
00034
00035 SickScanCommonNw::SickScanCommonNw()
00036 {
00037 m_state = CONSTRUCTED;
00038 m_beVerbose = false;
00039
00040 }
00041
00042 SickScanCommonNw::~SickScanCommonNw()
00043 {
00044
00045 if (isConnected() == true)
00046 {
00047
00048 disconnect();
00049 }
00050 }
00051
00052
00053
00054
00055
00056 bool SickScanCommonNw::disconnect()
00057 {
00058 closeTcpConnection();
00059
00060
00061 m_state = CONSTRUCTED;
00062 return true;
00063 }
00064
00065
00066
00067
00068
00069
00070 bool SickScanCommonNw::init(std::string ipAddress,
00071 unsigned short portNumber,
00072 Tcp::DisconnectFunction disconnectFunction,
00073 void* obj)
00074 {
00075 m_ipAddress = ipAddress;
00076 m_portNumber = portNumber;
00077 m_tcp.setDisconnectCallbackFunction(disconnectFunction, obj);
00078 return true;
00079 }
00080
00081
00082 bool SickScanCommonNw::setReadCallbackFunction(Tcp::ReadFunction readFunction,
00083 void* obj)
00084 {
00085 m_tcp.setReadCallbackFunction(readFunction, obj);
00086 return(true);
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096 bool SickScanCommonNw::connect()
00097 {
00098
00099 assert (m_state == CONSTRUCTED);
00100
00101
00102 m_numberOfBytesInReceiveBuffer = 0;
00103 m_numberOfBytesInResponseBuffer = 0;
00104
00105
00106
00107
00108
00109 bool success = openTcpConnection();
00110 if (success == true)
00111 {
00112
00113 m_state = CONNECTED;
00114
00115 }
00116 return success;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126 bool SickScanCommonNw::isConnected()
00127 {
00128 return (m_state == CONNECTED);
00129 }
00130
00131
00132
00133
00134
00140 bool SickScanCommonNw::openTcpConnection()
00141 {
00142
00143
00144 bool success = m_tcp.open(m_ipAddress, m_portNumber, m_beVerbose);
00145 if (success == false)
00146 {
00147
00148 return false;
00149 }
00150
00151 return true;
00152 }
00153
00154
00155
00156
00157
00158
00159 void SickScanCommonNw::closeTcpConnection()
00160 {
00161 if (m_tcp.isOpen())
00162 {
00163 m_tcp.close();
00164 }
00165 }
00166
00167
00168
00169
00170 void SickScanCommonNw::readCallbackFunctionS(void* obj, UINT8* buffer, UINT32& numOfBytes)
00171 {
00172 ((SickScanCommonNw*)obj)->readCallbackFunction(buffer, numOfBytes);
00173 }
00174
00175
00180 void SickScanCommonNw::readCallbackFunction(UINT8* buffer, UINT32& numOfBytes)
00181 {
00182 bool beVerboseHere = false;
00183 printInfoMessage("SickScanCommonNw::readCallbackFunction(): Called with " + toString(numOfBytes) + " available bytes.", beVerboseHere);
00184
00185 ScopedLock lock(&m_receiveDataMutex);
00186 UINT32 remainingSpace = sizeof(m_receiveBuffer) - m_numberOfBytesInReceiveBuffer;
00187 UINT32 bytesToBeTransferred = numOfBytes;
00188 if (remainingSpace < numOfBytes)
00189 {
00190 bytesToBeTransferred = remainingSpace;
00191
00192
00193 }
00194 else
00195 {
00196
00197
00198 }
00199
00200 if (bytesToBeTransferred > 0)
00201 {
00202
00203 memcpy(&(m_receiveBuffer[m_numberOfBytesInReceiveBuffer]), buffer, bytesToBeTransferred);
00204 m_numberOfBytesInReceiveBuffer += bytesToBeTransferred;
00205
00206 UINT32 size = 0;
00207
00208 while (1)
00209 {
00210
00211 SopasEventMessage frame = findFrameInReceiveBuffer();
00212
00213 size = frame.size();
00214 if (size == 0)
00215 {
00216
00217
00218 printInfoMessage("SickScanCommonNw::readCallbackFunction(): No complete frame in input buffer, we are done.", beVerboseHere);
00219
00220
00221 break;
00222 }
00223 else
00224 {
00225
00226 printInfoMessage("SickScanCommonNw::readCallbackFunction(): Processing a frame of length " + ::toString(frame.size()) + " bytes.", beVerboseHere);
00227 processFrame(frame);
00228 }
00229 }
00230 }
00231 else
00232 {
00233
00234
00235
00236 m_numberOfBytesInReceiveBuffer = 0;
00237 }
00238
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 SopasEventMessage SickScanCommonNw::findFrameInReceiveBuffer()
00251 {
00252 UINT32 frameLen = 0;
00253 UINT32 i;
00254
00255
00256 if (m_protocol == CoLa_A)
00257 {
00258
00259
00260
00261
00262 if (m_receiveBuffer[0] != 0x02)
00263 {
00264
00265 for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
00266 {
00267 if (m_receiveBuffer[i] == 0x02)
00268 {
00269 break;
00270 }
00271 }
00272
00273
00274 if (i >= m_numberOfBytesInReceiveBuffer)
00275 {
00276
00277 m_numberOfBytesInReceiveBuffer = 0;
00278 return SopasEventMessage();
00279 }
00280
00281
00282 UINT32 newLen = m_numberOfBytesInReceiveBuffer - i;
00283 memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), newLen);
00284 m_numberOfBytesInReceiveBuffer = newLen;
00285 }
00286
00287
00288 for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
00289 {
00290 if (m_receiveBuffer[i] == 0x03)
00291 {
00292 break;
00293 }
00294 }
00295
00296
00297 if (i >= m_numberOfBytesInReceiveBuffer)
00298 {
00299
00300 return SopasEventMessage();
00301 }
00302
00303
00304 frameLen = i + 1;
00305
00306 return SopasEventMessage(m_receiveBuffer, CoLa_A, frameLen);
00307 }
00308 else if (m_protocol == CoLa_B)
00309 {
00310 UINT32 magicWord;
00311 UINT32 payloadlength;
00312
00313 if (m_numberOfBytesInReceiveBuffer < 4)
00314 {
00315 return SopasEventMessage();
00316 }
00317 UINT16 pos = 0;
00318 magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00319 if (magicWord != 0x02020202)
00320 {
00321
00322 for (i = 1; i <= m_numberOfBytesInReceiveBuffer - 4; i++)
00323 {
00324 pos = i;
00325 magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00326 if (magicWord == 0x02020202)
00327 {
00328
00329 break;
00330 }
00331 }
00332
00333
00334 if (i > m_numberOfBytesInReceiveBuffer - 4)
00335 {
00336
00337 m_numberOfBytesInReceiveBuffer = 0;
00338 return SopasEventMessage();
00339 }
00340 else
00341 {
00342
00343 UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - i;
00344 memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), bytesToMove);
00345 m_numberOfBytesInReceiveBuffer = bytesToMove;
00346 }
00347 }
00348
00349
00350 if (m_numberOfBytesInReceiveBuffer < 9)
00351 {
00352
00353 printInfoMessage("SickScanCommonNw::findFrameInReceiveBuffer: Frame cannot be decoded yet, only " +
00354 ::toString(m_numberOfBytesInReceiveBuffer) + " bytes in the buffer.", m_beVerbose);
00355 return SopasEventMessage();
00356 }
00357
00358
00359 pos = 4;
00360 payloadlength = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00361 printInfoMessage("SickScanCommonNw::findFrameInReceiveBuffer: Decoded payload length is " + ::toString(payloadlength) + " bytes.", m_beVerbose);
00362
00363
00364 if (payloadlength > (sizeof(m_receiveBuffer) - 9))
00365 {
00366
00367 printWarning("SickScanCommonNw::findFrameInReceiveBuffer: Frame too big for receive buffer. Frame discarded with length:"
00368 + ::toString(payloadlength) + ".");
00369 m_numberOfBytesInReceiveBuffer = 0;
00370 return SopasEventMessage();
00371 }
00372 if ((payloadlength + 9) > m_numberOfBytesInReceiveBuffer)
00373 {
00374
00375 printInfoMessage("SickScanCommonNw::findFrameInReceiveBuffer: Frame not complete yet. Waiting for the rest of it (" +
00376 ::toString(payloadlength + 9 - m_numberOfBytesInReceiveBuffer) + " bytes missing).", m_beVerbose);
00377 return SopasEventMessage();
00378 }
00379
00380
00381 frameLen = payloadlength + 9;
00382
00383
00384
00385
00386 UINT8 temp = 0;
00387 UINT8 temp_xor = 0;
00388 UINT8 checkSum;
00389
00390
00391 pos = frameLen - 1;
00392 checkSum = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
00393
00394
00395 for (UINT16 i = 8; i < (frameLen - 1); i++)
00396 {
00397 pos = i;
00398 temp = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
00399 temp_xor = temp_xor ^ temp;
00400 }
00401
00402
00403 if (temp_xor != checkSum)
00404 {
00405 printWarning("SickScanCommonNw::findFrameInReceiveBuffer: Wrong checksum, Frame discarded.");
00406 m_numberOfBytesInReceiveBuffer = 0;
00407 return SopasEventMessage();
00408 }
00409
00410 return SopasEventMessage(m_receiveBuffer, CoLa_B, frameLen);
00411 }
00412
00413
00414 return SopasEventMessage();
00415 }
00416
00417
00418
00424 void SickScanCommonNw::sendCommandBuffer(UINT8* buffer, UINT16 len)
00425 {
00426 m_tcp.write(buffer, len);
00427 }
00428
00429
00430
00431
00437 void SickScanCommonNw::processFrame(SopasEventMessage& frame)
00438 {
00439
00440 if (m_protocol == CoLa_A)
00441 {
00442 printInfoMessage("SickScanCommonNw::processFrame: Calling processFrame_CoLa_A() with " + ::toString(frame.size()) + " bytes.", m_beVerbose);
00443
00444 }
00445 else if (m_protocol == CoLa_B)
00446 {
00447 printInfoMessage("SickScanCommonNw::processFrame: Calling processFrame_CoLa_B() with " + ::toString(frame.size()) + " bytes.", m_beVerbose);
00448
00449 }
00450 }
00451
00452
00453
00454
00455
00456
00457
00458 void SickScanCommonNw::copyFrameToResposeBuffer(UINT32 frameLength)
00459 {
00460 printInfoMessage("SickScanCommonNw::copyFrameToResposeBuffer: Copying a frame of " + ::toString(frameLength) +
00461 " bytes to response buffer.", m_beVerbose);
00462
00463 if (frameLength <= sizeof(m_responseBuffer))
00464 {
00465
00466 memcpy(m_responseBuffer, m_receiveBuffer, frameLength);
00467 m_numberOfBytesInResponseBuffer = frameLength;
00468 }
00469 else
00470 {
00471
00472 printError("SickScanCommonNw::copyFrameToResposeBuffer: Failed to copy frame (Length=" + ::toString(frameLength) +
00473 " bytes) to response buffer because the response buffer is too small (buffer size=" +
00474 ::toString(sizeof(m_responseBuffer)) + " bytes).");
00475 m_numberOfBytesInResponseBuffer = 0;
00476 }
00477 }
00478
00479
00480
00481
00482
00483
00484 void SickScanCommonNw::removeFrameFromReceiveBuffer(UINT32 frameLength)
00485 {
00486
00487 if (frameLength < m_numberOfBytesInReceiveBuffer)
00488 {
00489
00490 UINT32 newLen = m_numberOfBytesInReceiveBuffer - frameLength;
00491 printInfoMessage("SickScanCommonNw::removeFrameFromReceiveBuffer: Removing " + ::toString(frameLength) +
00492 " bytes from the input buffer. New length is " + ::toString(newLen) + " bytes.", m_beVerbose);
00493 memmove(m_receiveBuffer, &(m_receiveBuffer[frameLength]), newLen);
00494 m_numberOfBytesInReceiveBuffer = newLen;
00495 }
00496 else
00497 {
00498
00499 printInfoMessage("SickScanCommonNw::removeFrameFromReceiveBuffer: Done, no more data in input buffer.", m_beVerbose);
00500 m_numberOfBytesInReceiveBuffer = 0;
00501 }
00502 }
00503
00504
00505
00506
00507
00508
00509 SopasEventMessage::SopasEventMessage() :
00510 m_buffer(NULL), m_protocol(CoLa_A), m_frameLength(0)
00511 {
00512 }
00513
00514
00515
00516 SopasEventMessage::SopasEventMessage(BYTE* buffer, SopasProtocol protocol, UINT32 frameLength) :
00517 m_buffer(buffer), m_protocol(protocol), m_frameLength(frameLength)
00518 {
00519
00520 }
00521
00522
00523
00524 UINT32 SopasEventMessage::getPayLoadLength() const
00525 {
00526 UINT32 payLoadLength = 0;
00527
00528 switch (m_protocol)
00529 {
00530 case CoLa_A:
00531 payLoadLength = m_frameLength - 2;
00532 break;
00533 case CoLa_B:
00534 payLoadLength = m_frameLength - 9;
00535 }
00536
00537 return payLoadLength;
00538 }
00539
00540
00547 std::string SopasEventMessage::getCommandString() const
00548 {
00549 std::string commandString;
00550
00551 switch (m_protocol)
00552 {
00553 case CoLa_A:
00554 commandString = std::string((char*) &m_buffer[2], 2);
00555 break;
00556 case CoLa_B:
00557 commandString = std::string((char*) &m_buffer[9], 2);
00558 }
00559
00560 return commandString;
00561 }
00562
00563
00564
00572 BYTE* SopasEventMessage::getPayLoad()
00573 {
00574 BYTE* bufferPos = NULL;
00575
00576 switch (m_protocol)
00577 {
00578 case CoLa_A:
00579 bufferPos = &m_buffer[1];
00580 break;
00581 case CoLa_B:
00582 bufferPos = &m_buffer[8];
00583 break;
00584 }
00585
00586 return bufferPos;
00587 }
00588
00589
00596 BYTE* SopasEventMessage::getRawData()
00597 {
00598 BYTE* bufferPos = NULL;
00599 bufferPos = &m_buffer[0];
00600 return bufferPos;
00601 }
00602
00603
00604
00605 INT32 SopasEventMessage::getVariableIndex()
00606 {
00607 INT32 index = -1;
00608
00609
00610 BYTE* bufferPos = &getPayLoad()[3];
00611 switch (m_protocol)
00612 {
00613 case CoLa_A:
00614 index = (INT32)(colaa::decodeUINT16(bufferPos));
00615 break;
00616 case CoLa_B:
00617 index = (INT32)(colab::decodeUINT16(bufferPos));
00618 break;
00619 default:
00620 printError("SopasEventMessage::getVariableIndex: Unknown protocol!");
00621 }
00622
00623 return index;
00624 }