00001
00002
00003
00004
00005
00006
00007
00008 #include "sick_scan/tcp/SopasBase.hpp"
00009
00010 #include "sick_scan/tcp/errorhandler.hpp"
00011 #include "sick_scan/tcp/toolbox.hpp"
00012 #include "sick_scan/tcp/Mutex.hpp"
00013
00014 namespace devices
00015 {
00016
00017 #define SOPASBASE_VERSION "1.0.0"
00018
00019 const std::string SopasBase::EVENTNAME_SUBSCRIBE_EVALCASES("LFErec");
00020 const std::string SopasBase::EVENTNAME_SUBSCRIBE_SCANS("LMDscandata");
00021 const std::string SopasBase::METHODNAME_LOGIN("SetAccessMode");
00022 const std::string SopasBase::METHODNAME_LOGOUT("Run");
00023 const std::string SopasBase::METHODNAME_SET_SCANCONFIG("mLMPsetscancfg");
00024 const std::string SopasBase::METHODNAME_START_MEASURE("LMCstartmeas");
00025 const std::string SopasBase::METHODNAME_STOP_MEASURE("LMCstopmeas");
00026 const std::string SopasBase::VARIABLENAME_SCANCONFIG("LMPscancfg");
00027 const std::string SopasBase::VARIABLENAME_DATAOUTPUTRANGE("LMPoutputRange");
00028 const std::string SopasBase::VARIABLENAME_SCANDATACONFIG("LMDscandatacfg");
00029 const std::string SopasBase::VARIABLENAME_DEVICEIDENT("DeviceIdent");
00030
00031
00032 const std::string SopasBase::COMMAND_Read_Variable_ByIndex("RI");
00033 const std::string SopasBase::COMMAND_Write_Variable_ByIndex("WI");
00034 const std::string SopasBase::COMMAND_Invoke_Method_ByIndex("MI");
00035 const std::string SopasBase::COMMAND_Method_Result_ByIndex("AI");
00036 const std::string SopasBase::COMMAND_Register_Event_ByIndex("EI");
00037 const std::string SopasBase::COMMAND_Send_Event_ByIndex("SI");
00038
00039 const std::string SopasBase::COMMAND_Read_Variable_Answer("RA");
00040 const std::string SopasBase::COMMAND_Write_Variable_Answer("WA");
00041 const std::string SopasBase::COMMAND_Invoke_Method_Answer("MA");
00042 const std::string SopasBase::COMMAND_Method_Result_Answer("AA");
00043 const std::string SopasBase::COMMAND_Register_Event_Answer("EA");
00044 const std::string SopasBase::COMMAND_Event_Acknowledge("SA");
00045
00046 const std::string SopasBase::COMMAND_Read_Variable_ByName("RN");
00047 const std::string SopasBase::COMMAND_Write_Variable_ByName("WN");
00048 const std::string SopasBase::COMMAND_Invoke_Method_ByName("MN");
00049 const std::string SopasBase::COMMAND_Method_Result_ByName("AN");
00050 const std::string SopasBase::COMMAND_Register_Event_ByName("EN");
00051 const std::string SopasBase::COMMAND_Send_Event_ByName("SN");
00052
00053 const UINT16 SopasBase::INDEX_DEVICE_IDENT = 0;
00054
00055
00056
00057 SopasBase::SopasBase() :
00058 m_state(CONSTRUCTED)
00059 {
00060 m_beVerbose = false;
00061
00062 m_protocol = CoLa_A;
00063 }
00064
00065
00066
00067 SopasBase::~SopasBase()
00068 {
00069 printInfoMessage("Sopas device destructor: Running.", m_beVerbose);
00070
00071
00072
00073
00074 printInfoMessage("Sopas device destructor: Stopped, now disconnecting.", m_beVerbose);
00075
00076
00077 if (isConnected() == true)
00078 {
00079
00080 disconnect();
00081 }
00082
00083
00084
00085 printInfoMessage("Sopas device destructor: Done, device is deleted.", m_beVerbose);
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 bool SopasBase::init(SopasProtocol protocol,
00095 std::string ipAddress,
00096 UINT16 portNumber,
00097 bool weWantScanData,
00098 bool weWantFieldData,
00099 bool readOnlyMode,
00100 Tcp::DisconnectFunction disconnectFunction,
00101 void* obj)
00102 {
00103 m_protocol = protocol;
00104 m_ipAddress = ipAddress;
00105 m_portNumber = portNumber;
00106 m_weWantScanData = weWantScanData;
00107 m_weWantFieldData = weWantFieldData;
00108 setReadOnlyMode(readOnlyMode);
00109
00110 m_tcp.setDisconnectCallbackFunction(disconnectFunction, obj);
00111
00112 return true;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122 bool SopasBase::connect()
00123 {
00124 printInfoMessage("SopasBase::connect: Called.", m_beVerbose);
00125
00126 assert (m_state == CONSTRUCTED);
00127
00128
00129 m_numberOfBytesInReceiveBuffer = 0;
00130 m_numberOfBytesInResponseBuffer = 0;
00131
00132 m_scannerName = "";
00133 m_scannerVersion = "";
00134
00135
00136
00137 m_tcp.setReadCallbackFunction(&SopasBase::readCallbackFunctionS, this);
00138
00139 bool success = openTcpConnection();
00140 if (success == true)
00141 {
00142
00143 m_state = CONNECTED;
00144 printInfoMessage("SopasBase::connect: Reading scanner infos", m_beVerbose);
00145 success = action_getScannerTypeAndVersion();
00146
00147 if (success == true)
00148 {
00149 printInfoMessage("SopasBase::connect: Initialisation was successful.", m_beVerbose);
00150 }
00151 else
00152 {
00153 printError("SopasBase::connect: Failed to read scanner type and version.");
00154 }
00155 }
00156
00157 if (success == false)
00158 {
00159 printWarning("SopasBase::connect: Initialisation failed!");
00160 }
00161 else
00162 {
00163
00164 }
00165
00166 printInfoMessage("SopasBase::connect: Done.", m_beVerbose);
00167 return success;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177 bool SopasBase::isConnected()
00178 {
00179 return (m_state == CONNECTED);
00180 }
00181
00182
00183
00184
00185 bool SopasBase::disconnect()
00186 {
00187 closeTcpConnection();
00188
00189
00190 m_state = CONSTRUCTED;
00191 return true;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 void SopasBase::setReadOnlyMode(bool mode)
00201 {
00202 m_readOnlyMode = mode;
00203 }
00204
00205
00206
00207 bool SopasBase::isReadOnly()
00208 {
00209 return m_readOnlyMode;
00210 }
00211
00212
00213
00219 bool SopasBase::openTcpConnection()
00220 {
00221 printInfoMessage("SopasBase::openTcpConnection: Connecting TCP/IP connection to " + m_ipAddress + ":" + toString(m_portNumber) + " ...", m_beVerbose);
00222
00223 bool success = m_tcp.open(m_ipAddress, m_portNumber, m_beVerbose);
00224 if (success == false)
00225 {
00226 printError("SopasBase::openTcpConnection: ERROR: Failed to establish TCP connection, aborting!");
00227 return false;
00228 }
00229
00230 return true;
00231 }
00232
00233
00234
00235
00236
00237
00238 void SopasBase::closeTcpConnection()
00239 {
00240 if (m_tcp.isOpen())
00241 {
00242 m_tcp.close();
00243 }
00244 }
00245
00246
00247
00248
00249 void SopasBase::readCallbackFunctionS(void* obj, UINT8* buffer, UINT32& numOfBytes)
00250 {
00251 ((SopasBase*)obj)->readCallbackFunction(buffer, numOfBytes);
00252 }
00253
00254
00259 void SopasBase::readCallbackFunction(UINT8* buffer, UINT32& numOfBytes)
00260 {
00261 bool beVerboseHere = false;
00262 printInfoMessage("SopasBase::readCallbackFunction(): Called with " + toString(numOfBytes) + " available bytes.", beVerboseHere);
00263
00264 ScopedLock lock(&m_receiveDataMutex);
00265 UINT32 remainingSpace = sizeof(m_receiveBuffer) - m_numberOfBytesInReceiveBuffer;
00266 UINT32 bytesToBeTransferred = numOfBytes;
00267 if (remainingSpace < numOfBytes)
00268 {
00269 bytesToBeTransferred = remainingSpace;
00270 printWarning("SopasBase::readCallbackFunction(): Input buffer space is to small, transferring only " +
00271 ::toString(bytesToBeTransferred) + " of " + ::toString(numOfBytes) + " bytes.");
00272 }
00273 else
00274 {
00275 printInfoMessage("SopasBase::readCallbackFunction(): Transferring " + ::toString(bytesToBeTransferred) +
00276 " bytes from TCP to input buffer.", beVerboseHere);
00277 }
00278
00279 if (bytesToBeTransferred > 0)
00280 {
00281
00282 memcpy(&(m_receiveBuffer[m_numberOfBytesInReceiveBuffer]), buffer, bytesToBeTransferred);
00283 m_numberOfBytesInReceiveBuffer += bytesToBeTransferred;
00284
00285 UINT32 size = 0;
00286
00287 while (1)
00288 {
00289
00290 SopasEventMessage frame = findFrameInReceiveBuffer();
00291
00292 size = frame.size();
00293 if (size == 0)
00294 {
00295
00296
00297 printInfoMessage("SopasBase::readCallbackFunction(): No complete frame in input buffer, we are done.", beVerboseHere);
00298
00299
00300 break;
00301 }
00302 else
00303 {
00304
00305 printInfoMessage("SopasBase::readCallbackFunction(): Processing a frame of length " + ::toString(frame.size()) + " bytes.", beVerboseHere);
00306 processFrame(frame);
00307 }
00308 }
00309 }
00310 else
00311 {
00312
00313
00314
00315 m_numberOfBytesInReceiveBuffer = 0;
00316 }
00317
00318 printInfoMessage("SopasBase::readCallbackFunction(): Leaving. Current input buffer fill level is " +
00319 ::toString(m_numberOfBytesInReceiveBuffer) + " bytes.", beVerboseHere);
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331 SopasEventMessage SopasBase::findFrameInReceiveBuffer()
00332 {
00333 UINT32 frameLen = 0;
00334 UINT32 i;
00335
00336
00337 if (m_protocol == CoLa_A)
00338 {
00339
00340
00341
00342
00343 if (m_receiveBuffer[0] != 0x02)
00344 {
00345
00346 for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
00347 {
00348 if (m_receiveBuffer[i] == 0x02)
00349 {
00350 break;
00351 }
00352 }
00353
00354
00355 if (i >= m_numberOfBytesInReceiveBuffer)
00356 {
00357
00358 m_numberOfBytesInReceiveBuffer = 0;
00359 return SopasEventMessage();
00360 }
00361
00362
00363 UINT32 newLen = m_numberOfBytesInReceiveBuffer - i;
00364 memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), newLen);
00365 m_numberOfBytesInReceiveBuffer = newLen;
00366 }
00367
00368
00369 for (i = 1; i < m_numberOfBytesInReceiveBuffer; i++)
00370 {
00371 if (m_receiveBuffer[i] == 0x03)
00372 {
00373 break;
00374 }
00375 }
00376
00377
00378 if (i >= m_numberOfBytesInReceiveBuffer)
00379 {
00380
00381 return SopasEventMessage();
00382 }
00383
00384
00385 frameLen = i + 1;
00386
00387 return SopasEventMessage(m_receiveBuffer, CoLa_A, frameLen);
00388 }
00389 else if (m_protocol == CoLa_B)
00390 {
00391 UINT32 magicWord;
00392 UINT32 payloadlength;
00393
00394 if (m_numberOfBytesInReceiveBuffer < 4)
00395 {
00396 return SopasEventMessage();
00397 }
00398 UINT16 pos = 0;
00399 magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00400 if (magicWord != 0x02020202)
00401 {
00402
00403 for (i = 1; i <= m_numberOfBytesInReceiveBuffer - 4; i++)
00404 {
00405 pos = i;
00406 magicWord = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00407 if (magicWord == 0x02020202)
00408 {
00409
00410 break;
00411 }
00412 }
00413
00414
00415 if (i > m_numberOfBytesInReceiveBuffer - 4)
00416 {
00417
00418 m_numberOfBytesInReceiveBuffer = 0;
00419 return SopasEventMessage();
00420 }
00421 else
00422 {
00423
00424 UINT32 bytesToMove = m_numberOfBytesInReceiveBuffer - i;
00425 memmove(&(m_receiveBuffer[0]), &(m_receiveBuffer[i]), bytesToMove);
00426 m_numberOfBytesInReceiveBuffer = bytesToMove;
00427 }
00428 }
00429
00430
00431 if (m_numberOfBytesInReceiveBuffer < 9)
00432 {
00433
00434 printInfoMessage("SopasBase::findFrameInReceiveBuffer: Frame cannot be decoded yet, only " +
00435 ::toString(m_numberOfBytesInReceiveBuffer) + " bytes in the buffer.", m_beVerbose);
00436 return SopasEventMessage();
00437 }
00438
00439
00440 pos = 4;
00441 payloadlength = colab::getIntegerFromBuffer<UINT32>(m_receiveBuffer, pos);
00442 printInfoMessage("SopasBase::findFrameInReceiveBuffer: Decoded payload length is " + ::toString(payloadlength) + " bytes.", m_beVerbose);
00443
00444
00445 if (payloadlength > (sizeof(m_receiveBuffer) - 9))
00446 {
00447
00448 printWarning("SopasBase::findFrameInReceiveBuffer: Frame too big for receive buffer. Frame discarded with length:"
00449 + ::toString(payloadlength) + ".");
00450 m_numberOfBytesInReceiveBuffer = 0;
00451 return SopasEventMessage();
00452 }
00453 if ((payloadlength + 9) > m_numberOfBytesInReceiveBuffer)
00454 {
00455
00456 printInfoMessage("SopasBase::findFrameInReceiveBuffer: Frame not complete yet. Waiting for the rest of it (" +
00457 ::toString(payloadlength + 9 - m_numberOfBytesInReceiveBuffer) + " bytes missing).", m_beVerbose);
00458 return SopasEventMessage();
00459 }
00460
00461
00462 frameLen = payloadlength + 9;
00463
00464
00465
00466
00467 UINT8 temp = 0;
00468 UINT8 temp_xor = 0;
00469 UINT8 checkSum;
00470
00471
00472 pos = frameLen - 1;
00473 checkSum = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
00474
00475
00476 for (UINT16 i = 8; i < (frameLen - 1); i++)
00477 {
00478 pos = i;
00479 temp = colab::getIntegerFromBuffer<UINT8>(m_receiveBuffer, pos);
00480 temp_xor = temp_xor ^ temp;
00481 }
00482
00483
00484 if (temp_xor != checkSum)
00485 {
00486 printWarning("SopasBase::findFrameInReceiveBuffer: Wrong checksum, Frame discarded.");
00487 m_numberOfBytesInReceiveBuffer = 0;
00488 return SopasEventMessage();
00489 }
00490
00491 return SopasEventMessage(m_receiveBuffer, CoLa_B, frameLen);
00492 }
00493
00494
00495 return SopasEventMessage();
00496 }
00497
00498
00499
00505 void SopasBase::sendCommandBuffer(UINT8* buffer, UINT16 len)
00506 {
00507 UINT8 sendBuffer[1024];
00508
00509 assert (len < 1000);
00510 assert (m_tcp.isOpen() == true);
00511
00512
00513 if (m_protocol == CoLa_A)
00514 {
00515 colaa::addFrameToBuffer(sendBuffer, buffer, &len);
00516 }
00517 else if (m_protocol == CoLa_B)
00518 {
00519 colab::addFrameToBuffer(sendBuffer, buffer, &len);
00520 }
00521
00522
00523
00524
00525
00526 m_tcp.write(sendBuffer, len);
00527 }
00528
00529
00530
00539 bool SopasBase::receiveAnswer(SopasCommand cmd, std::string name, UINT32 timeout, SopasAnswer*& answer)
00540 {
00541 switch (m_protocol)
00542 {
00543 case CoLa_A:
00544 printInfoMessage("SopasBase::receiveAnswer: calling receiveAnswer_CoLa_A.", m_beVerbose);
00545 return receiveAnswer_CoLa_A(cmd, name, timeout, answer);
00546 case CoLa_B:
00547 printInfoMessage("SopasBase::receiveAnswer: calling receiveAnswer_CoLa_B.", m_beVerbose);
00548 return receiveAnswer_CoLa_B(cmd, name, timeout, answer);
00549 default:
00550 printWarning("SopasBase::receiveAnswer: Wrong protocol (is either not CoLa-A or CoLa-B).");
00551 }
00552
00553 return false;
00554 }
00555
00556
00557
00566 bool SopasBase::receiveAnswer(SopasCommand cmd, UINT16 index, UINT32 timeout, SopasAnswer*& answer)
00567 {
00568 switch (m_protocol)
00569 {
00570 case CoLa_A:
00571 printInfoMessage("SopasBase::receiveAnswer: Calling receiveAnswer_CoLa_A.", m_beVerbose);
00572 return receiveAnswer_CoLa_A(cmd, index, timeout, answer);
00573 case CoLa_B:
00574 printInfoMessage("SopasBase::receiveAnswer: Calling receiveAnswer_CoLa_B.", m_beVerbose);
00575 return receiveAnswer_CoLa_B(cmd, index, timeout, answer);
00576 default:
00577 printWarning("SopasBase::receiveAnswer: Wrong protocol (is either not CoLa-A or CoLa-B).");
00578 }
00579
00580 return false;
00581 }
00582
00583
00584
00585
00586
00587 bool SopasBase::receiveAnswer_CoLa_A(SopasCommand cmd, UINT16 index, UINT32 timeout, SopasAnswer*& answer)
00588 {
00589 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: entering function.", m_beVerbose);
00590
00591 SopasCommand receivedCommand;
00592 std::string rxData;
00593 if (timeout == 0)
00594 {
00595 timeout = 1;
00596 }
00597
00598
00599 for (UINT32 i = 0; i < timeout; i++)
00600 {
00601
00602 {
00603 ScopedLock lock(&m_receiveDataMutex);
00604 if (m_numberOfBytesInResponseBuffer > 0)
00605 {
00606 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: Response received (len= " +
00607 ::toString(m_numberOfBytesInResponseBuffer) +
00608 " bytes).", m_beVerbose);
00609 rxData = colaa::convertRxBufferToString(m_responseBuffer, m_numberOfBytesInResponseBuffer);
00610 m_numberOfBytesInResponseBuffer = 0;
00611 }
00612 }
00613
00614 if (rxData.length() > 0)
00615 {
00616
00617 receivedCommand = colaA_decodeCommand(&rxData);
00618
00619 if (cmd == receivedCommand)
00620 {
00621
00622
00623 if (receivedCommand == WA)
00624 {
00625
00626 return true;
00627 }
00628
00629 UINT16 receivedIndex = colaa::decodeUINT16(&rxData);
00630
00631 if (receivedIndex == index)
00632 {
00633
00634 if (cmd == RA || cmd == AN)
00635 {
00636 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: *** receive answer with data in return *** ", m_beVerbose);
00637
00638 answer = new SopasAnswer((BYTE*)rxData.c_str(), rxData.length());
00639 m_numberOfBytesInResponseBuffer = 0;
00640 return true;
00641 }
00642 else if (receivedCommand == EA)
00643 {
00644
00645 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: Event (by index) successfully (un)registered: " +
00646 ::toString(receivedIndex) + ".", m_beVerbose);
00647
00648 m_numberOfBytesInResponseBuffer = 0;
00649 return true;
00650 }
00651 }
00652 else
00653 {
00654 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: This is not the answer we are waiting for. ", m_beVerbose);
00655 m_numberOfBytesInResponseBuffer = 0;
00656 }
00657 }
00658
00659 else if (receivedCommand == FA)
00660 {
00661 printInfoMessage("SopasBase::Error answer received: FA " + rxData + ".", m_beVerbose);
00662 answer = new SopasAnswer((BYTE*)rxData.c_str(), rxData.length());
00663 return false;
00664 }
00665 else
00666 {
00667 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: This is not the answer we are waiting for. ", m_beVerbose);
00668 m_numberOfBytesInResponseBuffer = 0;
00669 rxData.clear();
00670 }
00671 }
00672 else
00673 {
00674
00675 usleep(1000);
00676 }
00677 }
00678
00679
00680 return false;
00681 }
00682
00683
00684
00685 bool SopasBase::receiveAnswer_CoLa_A(SopasCommand cmd, std::string name, UINT32 timeout, SopasAnswer*& answer)
00686 {
00687 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: entering function.", m_beVerbose);
00688
00689 SopasCommand receivedCommand;
00690 std::string rxData;
00691 if (timeout == 0)
00692 {
00693 timeout = 1;
00694 }
00695
00696
00697 for (UINT32 i = 0; i < timeout; i++)
00698 {
00699
00700 {
00701 ScopedLock lock(&m_receiveDataMutex);
00702 if (m_numberOfBytesInResponseBuffer > 0)
00703 {
00704 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: Response received (len= " +
00705 ::toString(m_numberOfBytesInResponseBuffer) + " bytes).", m_beVerbose);
00706 rxData = colaa::convertRxBufferToString(m_responseBuffer, m_numberOfBytesInResponseBuffer);
00707 m_numberOfBytesInResponseBuffer = 0;
00708 }
00709 }
00710
00711 if (rxData.length() > 0)
00712 {
00713
00714 receivedCommand = colaA_decodeCommand(&rxData);
00715
00716 if (cmd == receivedCommand)
00717 {
00718
00719
00720 if (receivedCommand == WA)
00721 {
00722
00723 return true;
00724 }
00725
00726 std::string receivedName = colaa::decodeString(&rxData);
00727
00728 if (receivedName == name)
00729 {
00730
00731 if (cmd == RA || cmd == AN)
00732 {
00733 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: *** receive answer with data in return *** ", m_beVerbose);
00734
00735 answer = new SopasAnswer((BYTE*)rxData.c_str(), rxData.length());
00736 m_numberOfBytesInResponseBuffer = 0;
00737 return true;
00738 }
00739 else if (receivedCommand == EA)
00740 {
00741
00742
00743 printInfoMessage("SopasBase:: Event successfully (un)registered: " + receivedName + ".", m_beVerbose);
00744 m_numberOfBytesInResponseBuffer = 0;
00745 return true;
00746 }
00747 }
00748 else
00749 {
00750 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: This is not the answer we are waiting for.", m_beVerbose);
00751 m_numberOfBytesInResponseBuffer = 0;
00752 }
00753 }
00754
00755 else if (receivedCommand == FA)
00756 {
00757 printInfoMessage("SopasBase:: Error answer received: FA " + rxData + ".", true);
00758 answer = new SopasAnswer((BYTE*)rxData.c_str(), rxData.length());
00759 return false;
00760 }
00761 else
00762 {
00763 printInfoMessage("SopasBase::receiveAnswer_CoLa_A: This is not the answer we are waiting for.", m_beVerbose);
00764 m_numberOfBytesInResponseBuffer = 0;
00765 rxData.clear();
00766 }
00767 }
00768 else
00769 {
00770
00771 usleep(1000);
00772 }
00773 }
00774
00775
00776 return false;
00777 }
00778
00779
00780
00781 bool SopasBase::receiveAnswer_CoLa_B(SopasCommand cmd, std::string name, UINT32 timeout, SopasAnswer*& answer)
00782 {
00783 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: Entering function.", m_beVerbose);
00784
00785 SopasCommand receivedCommand;
00786 UINT16 nextData;
00787 std::string receivedName;
00788
00789 if (timeout == 0)
00790 {
00791 timeout = 1;
00792 }
00793
00794
00795 for (UINT32 i = 0; i < timeout; i++)
00796 {
00797 if (m_numberOfBytesInResponseBuffer > 0)
00798 {
00799
00800
00801
00802
00803
00804
00805 ScopedLock lock(&m_receiveDataMutex);
00806
00807
00808 SopasEventMessage frame (m_responseBuffer, CoLa_B, m_numberOfBytesInResponseBuffer);
00809
00810
00811
00812 receivedCommand = stringToSopasCommand(frame.getCommandString());
00813
00814 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: receivedCommand= " + frame.getCommandString() + ".", m_beVerbose);
00815
00816 if (receivedCommand == FA)
00817 {
00818
00819 nextData = 0;
00820 UINT16 errorCode = colab::getIntegerFromBuffer<UINT16>(&(m_responseBuffer[11]), nextData);
00821 printWarning("SopasBase::receiveAnswer_CoLa_B: Error from sensor! Code=" + toString(errorCode) +
00822 ", meaning: " + convertSopasErrorCodeToText(errorCode) + ".");
00823 m_numberOfBytesInResponseBuffer = 0;
00824 return false;
00825 }
00826
00827 if (cmd != receivedCommand)
00828 {
00829
00830
00831
00832 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: This is not the answer (" + sopasCommandToString(receivedCommand) + ") are waiting for ("
00833 + sopasCommandToString(cmd) + ").", m_beVerbose);
00834 m_numberOfBytesInResponseBuffer = 0;
00835 return false;
00836 }
00837
00838
00839
00840
00841 receivedName = colab::getIdentifierFromBuffer(m_responseBuffer, nextData, sizeof(m_responseBuffer));
00842
00843 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: receicedName= " + receivedName + ".", m_beVerbose);
00844
00845 if (name != receivedName)
00846 {
00847
00848 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: This is not the answer we are waiting for. (" + frame.getCommandString() +
00849 ", " + name + ").", m_beVerbose);
00850
00851 m_numberOfBytesInResponseBuffer = 0;
00852 return false;
00853 }
00854
00855 if (receivedCommand == WA)
00856 {
00857
00858 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: Variable successfully set.", m_beVerbose);
00859 m_numberOfBytesInResponseBuffer = 0;
00860 return true;
00861 }
00862
00863 else if (receivedCommand == EA)
00864 {
00865 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: Answer to (un)subscribe event " + receivedName + ".", m_beVerbose);
00866 m_numberOfBytesInResponseBuffer = 0;
00867 return true;
00868 }
00869
00870 else if (receivedCommand == AN )
00871 {
00872 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: Answer to method call " + receivedName + ".", m_beVerbose);
00873 answer = new SopasAnswer(&m_responseBuffer[nextData], m_numberOfBytesInResponseBuffer - nextData);
00874 m_numberOfBytesInResponseBuffer = 0;
00875 return true;
00876 }
00877 else if (receivedCommand == RA)
00878 {
00879
00880 answer = new SopasAnswer(&m_responseBuffer[nextData], m_numberOfBytesInResponseBuffer - nextData);
00881 m_numberOfBytesInResponseBuffer = 0;
00882 return true;
00883 }
00884
00885 else if (receivedCommand == CMD_UNKNOWN)
00886 {
00887 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: Unkown Sopas command.", true);
00888 m_numberOfBytesInResponseBuffer = 0;
00889 return false;
00890 }
00891 else
00892 {
00893
00894 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: Untreated Sopas command.", m_beVerbose);
00895 m_numberOfBytesInResponseBuffer = 0;
00896 return false;
00897 }
00898
00899 }
00900 else
00901 {
00902
00903 usleep(1000);
00904 }
00905 }
00906
00907
00908 printInfoMessage("SopasBase::receiveAnswer_CoLa_B: Leaving with timeout.", m_beVerbose);
00909
00910 return false;
00911 }
00912
00913
00914
00915
00916 std::string SopasBase::convertSopasErrorCodeToText(UINT16 errorCode)
00917 {
00918 switch (errorCode)
00919 {
00920 case 0:
00921 return "Sopas_Ok";
00922 case 1:
00923 return "Sopas_Error_METHODIN_ACCESSDENIED";
00924 case 2:
00925 return "Sopas_Error_METHODIN_UNKNOWNINDEX";
00926 case 3:
00927 return "Sopas_Error_VARIABLE_UNKNOWNINDEX";
00928 case 4:
00929 return "Sopas_Error_LOCALCONDITIONFAILED";
00930 case 5:
00931 return "Sopas_Error_INVALID_DATA";
00932 case 6:
00933 return "Sopas_Error_UNKNOWN_ERROR";
00934 case 7:
00935 return "Sopas_Error_BUFFER_OVERFLOW";
00936 case 8:
00937 return "Sopas_Error_BUFFER_UNDERFLOW";
00938 case 9:
00939 return "Sopas_Error_ERROR_UNKNOWN_TYPE";
00940 case 10:
00941 return "Sopas_Error_VARIABLE_WRITE_ACCESSDENIED";
00942 case 11:
00943 return "Sopas_Error_UNKNOWN_CMD_FOR_NAMESERVER";
00944 case 12:
00945 return "Sopas_Error_UNKNOWN_COLA_COMMAND";
00946 case 13:
00947 return "Sopas_Error_METHODIN_SERVER_BUSY";
00948 case 14:
00949 return "Sopas_Error_FLEX_OUT_OF_BOUNDS";
00950 case 15:
00951 return "Sopas_Error_EVENTREG_UNKNOWNINDEX";
00952 case 16:
00953 return "Sopas_Error_COLA_A_VALUE_OVERFLOW";
00954 case 17:
00955 return "Sopas_Error_COLA_A_INVALID_CHARACTER";
00956 case 18:
00957 return "Sopas_Error_OSAI_NO_MESSAGE";
00958 case 19:
00959 return "Sopas_Error_OSAI_NO_ANSWER_MESSAGE";
00960 case 20:
00961 return "Sopas_Error_INTERNAL";
00962 case 21:
00963 return "Sopas_Error_HubAddressCorrupted";
00964 case 22:
00965 return "Sopas_Error_HubAddressDecoding";
00966 case 23:
00967 return "Sopas_Error_HubAddressAddressExceeded";
00968 case 24:
00969 return "Sopas_Error_HubAddressBlankExpected";
00970 case 0x19:
00971 return "Sopas_Error_AsyncMethodsAreSuppressed";
00972 case 0x20:
00973 return "Sopas_Error_ComplexArraysNotSupported";
00974 default:
00975 return "(unknown_Sopas_error_code)";
00976 }
00977
00978 return "(unknown_Sopas_error_code)";
00979 }
00980
00981
00982
00983
00984 bool SopasBase::receiveAnswer_CoLa_B(SopasCommand cmd, UINT16 index, UINT32 timeout, SopasAnswer*& answer)
00985 {
00986 bool beVerboseHere = m_beVerbose;
00987
00988
00989 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: Entering function.", beVerboseHere);
00990
00991 SopasCommand receivedCommand;
00992 UINT16 nextData;
00993
00994 if (timeout == 0)
00995 {
00996 timeout = 1;
00997 }
00998
00999
01000 for (UINT32 i = 0; i < timeout; i++)
01001 {
01002 if (m_numberOfBytesInResponseBuffer > 0)
01003 {
01004 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: There is something in receive buffer.", beVerboseHere);
01005
01006
01007 ScopedLock lock(&m_receiveDataMutex);
01008
01009
01010
01011
01012 SopasEventMessage frame (m_responseBuffer, CoLa_B, m_numberOfBytesInResponseBuffer);
01013
01014
01015 receivedCommand = stringToSopasCommand(frame.getCommandString());
01016
01017 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: ReceivedCommand= " + frame.getCommandString() + ".", beVerboseHere);
01018
01019 nextData = 11;
01020 UINT16 receivedIndex = colab::getIntegerFromBuffer<UINT16>(m_responseBuffer, nextData);
01021
01022 if (receivedCommand == FA)
01023 {
01024
01025
01026 printWarning("SopasBase::receiveAnswer_CoLa_B_idx: Error from sensor! Code=" + toString(receivedIndex) +
01027 ", meaning: " + convertSopasErrorCodeToText(receivedIndex) + ".");
01028 m_numberOfBytesInResponseBuffer = 0;
01029 return false;
01030 }
01031
01032 else if (index != receivedIndex)
01033 {
01034
01035
01036
01037 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: This is not the index we are waiting for (expected="
01038 + toString(index) + ", received=" + toString(receivedIndex) + ")." , beVerboseHere);
01039 m_numberOfBytesInResponseBuffer = 0;
01040 return false;
01041 }
01042
01043 else if (cmd != receivedCommand)
01044 {
01045
01046
01047 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: This is not the answer (" + sopasCommandToString(receivedCommand) +
01048 ") we are waiting for (" + sopasCommandToString(cmd) + "). ", beVerboseHere);
01049 m_numberOfBytesInResponseBuffer = 0;
01050 return false;
01051 }
01052
01053 else if (receivedCommand == WA)
01054 {
01055
01056 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: Variable successfully set.", beVerboseHere);
01057 m_numberOfBytesInResponseBuffer = 0;
01058 return true;
01059 }
01060
01061 else if (receivedCommand == EA)
01062 {
01063
01064 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: Event successfully (un)registered: " + ::toString(receivedIndex) + ".", beVerboseHere);
01065 m_numberOfBytesInResponseBuffer = 0;
01066 return true;
01067 }
01068
01069 else if (receivedCommand == AI )
01070 {
01071
01072 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: Answer to method call with index " + ::toString(receivedIndex) + ".", beVerboseHere);
01073 answer = new SopasAnswer(&m_responseBuffer[nextData], m_numberOfBytesInResponseBuffer - nextData);
01074 m_numberOfBytesInResponseBuffer = 0;
01075 return true;
01076 }
01077
01078 else if (receivedCommand == RA)
01079 {
01080
01081 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: Answer to read variable with index " + ::toString(receivedIndex) + ".", beVerboseHere);
01082
01083 answer = new SopasAnswer(&m_responseBuffer[nextData], m_numberOfBytesInResponseBuffer - nextData);
01084 m_numberOfBytesInResponseBuffer = 0;
01085 return true;
01086 }
01087
01088 else if (receivedCommand == CMD_UNKNOWN)
01089 {
01090 printWarning("SopasBase::receiveAnswer_CoLa_B_idx: Unknown Sopas command.");
01091 m_numberOfBytesInResponseBuffer = 0;
01092 return false;
01093 }
01094 else
01095 {
01096
01097 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: Untreated Sopas command.", beVerboseHere);
01098 m_numberOfBytesInResponseBuffer = 0;
01099 return false;
01100 }
01101 }
01102 else
01103 {
01104
01105 usleep(1000);
01106 }
01107 }
01108
01109
01110 printInfoMessage("SopasBase::receiveAnswer_CoLa_B_idx: Leaving with timeout.", beVerboseHere);
01111
01112
01113 return false;
01114 }
01115
01116
01117
01123 void SopasBase::processFrame(SopasEventMessage& frame)
01124 {
01125
01126 if (m_protocol == CoLa_A)
01127 {
01128 printInfoMessage("SopasBase::processFrame: Calling processFrame_CoLa_A() with " + ::toString(frame.size()) + " bytes.", m_beVerbose);
01129 processFrame_CoLa_A(frame);
01130 }
01131 else if (m_protocol == CoLa_B)
01132 {
01133 printInfoMessage("SopasBase::processFrame: Calling processFrame_CoLa_B() with " + ::toString(frame.size()) + " bytes.", m_beVerbose);
01134 processFrame_CoLa_B(frame);
01135 }
01136 }
01137
01138
01139
01140
01141
01142
01143
01144
01145 void SopasBase::processFrame_CoLa_A(SopasEventMessage& frame)
01146 {
01147 std::string command;
01148 command = m_receiveBuffer[2];
01149 command += m_receiveBuffer[3];
01150 assert (command.length() == 2);
01151
01152
01153
01154
01155
01156 if (frame.getMessageType() == MSG_SEND_EVENT)
01157 {
01158 if (frame.size() > 8)
01159 {
01160
01161 std::string eventName;
01162 UINT32 i = 5;
01163 while (m_receiveBuffer[i] != ' ' && i < frame.size() )
01164 {
01165
01166 i++;
01167 }
01168 eventName = std::string((char*) m_receiveBuffer, 5, i - 5);
01169
01170 if (m_decoderFunctionMapByName[eventName] != NULL)
01171 {
01172
01173 m_decoderFunctionMapByName[eventName](frame);
01174 }
01175 else
01176 {
01177
01178 printWarning("SopasBase::Received an unknown event! Event name is: " + eventName + ".");
01179 }
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 }
01209 else
01210 {
01211
01212 printWarning("SopasBase::Received a very short (and unknown) event! Frame length is " + ::toString(frame.size()) +
01213 " bytes.");
01214 }
01215 }
01216 else
01217 {
01218
01219
01220 copyFrameToResposeBuffer(frame.size());
01221 }
01222
01223
01224 removeFrameFromReceiveBuffer(frame.size());
01225 }
01226
01227
01228
01229
01230
01231
01232
01233
01234 void SopasBase::processFrame_CoLa_B(SopasEventMessage& frame)
01235 {
01236
01237 std::string command = colab::getCommandStringFromBuffer(m_receiveBuffer);
01238
01239 printInfoMessage("SopasBase::processFrame_CoLa_B: Command is " + command + ".", m_beVerbose);
01240
01241
01242
01243
01244
01245 bool frameWasProcessed = false;
01246 if (frame.getMessageType() == MSG_SEND_EVENT)
01247 {
01248 if (frame.size() > 12)
01249 {
01250
01251
01252 std::string eventName;
01253 UINT32 eventIndex = 0;
01254 UINT16 pos = 0;
01255
01256 switch (frame.getEncodingType())
01257 {
01258 case ByIndex:
01259 pos = 11;
01260 eventIndex = colab::getIntegerFromBuffer<UINT16>(m_receiveBuffer, pos);
01261 eventName = m_indexToNameMap[eventIndex];
01262
01263 switch (eventIndex)
01264 {
01265 case 0x11:
01266 eventName = EVENTNAME_SUBSCRIBE_SCANS;
01267 scanDataDecoder(frame);
01268 frameWasProcessed = true;
01269 break;
01270 case 0x29:
01271 eventName = EVENTNAME_SUBSCRIBE_EVALCASES;
01272 evalCaseResultDecoder(frame);
01273 frameWasProcessed = true;
01274 break;
01275 default:
01276 ;
01277 }
01278 break;
01279
01280 default:
01281 printWarning("SopasBase::processFrame_CoLa_B: Decoding of events by name is not implemented yet.");
01282 eventName = frame.getVariableName();
01283 break;
01284 }
01285
01286 if (frameWasProcessed == false)
01287 {
01288
01289 printWarning("SopasBase::processFrame_CoLa_B: Don't know how to process the incoming event with the short name <" +
01290 eventName + "> and the index " + ::toString(eventIndex) + ", ignoring it!");
01291 }
01292 }
01293 else
01294 {
01295
01296 printWarning("SopasBase::processFrame_CoLa_B: Received a very short (and unknown) event! Frame length is " + ::toString(frame.size()) + " bytes.");
01297 }
01298 }
01299 else
01300 {
01301
01302 copyFrameToResposeBuffer(frame.size());
01303 }
01304
01305 removeFrameFromReceiveBuffer(frame.size());
01306 }
01307
01308
01309
01310
01311
01312
01313
01314
01315 void SopasBase::copyFrameToResposeBuffer(UINT32 frameLength)
01316 {
01317 printInfoMessage("SopasBase::copyFrameToResposeBuffer: Copying a frame of " + ::toString(frameLength) +
01318 " bytes to response buffer.", m_beVerbose);
01319
01320 if (frameLength <= sizeof(m_responseBuffer))
01321 {
01322
01323 memcpy(m_responseBuffer, m_receiveBuffer, frameLength);
01324 m_numberOfBytesInResponseBuffer = frameLength;
01325 }
01326 else
01327 {
01328
01329 printError("SopasBase::copyFrameToResposeBuffer: Failed to copy frame (Length=" + ::toString(frameLength) +
01330 " bytes) to response buffer because the response buffer is too small (buffer size=" +
01331 ::toString(sizeof(m_responseBuffer)) + " bytes).");
01332 m_numberOfBytesInResponseBuffer = 0;
01333 }
01334 }
01335
01336
01337
01338
01339
01340
01341 void SopasBase::removeFrameFromReceiveBuffer(UINT32 frameLength)
01342 {
01343
01344 if (frameLength < m_numberOfBytesInReceiveBuffer)
01345 {
01346
01347 UINT32 newLen = m_numberOfBytesInReceiveBuffer - frameLength;
01348 printInfoMessage("SopasBase::removeFrameFromReceiveBuffer: Removing " + ::toString(frameLength) +
01349 " bytes from the input buffer. New length is " + ::toString(newLen) + " bytes.", m_beVerbose);
01350 memmove(m_receiveBuffer, &(m_receiveBuffer[frameLength]), newLen);
01351 m_numberOfBytesInReceiveBuffer = newLen;
01352 }
01353 else
01354 {
01355
01356 printInfoMessage("SopasBase::removeFrameFromReceiveBuffer: Done, no more data in input buffer.", m_beVerbose);
01357 m_numberOfBytesInReceiveBuffer = 0;
01358 }
01359 }
01360
01361
01362
01368 SopasBase::SopasCommand SopasBase::colaA_decodeCommand(std::string* rxData)
01369 {
01370 return stringToSopasCommand(colaa::getNextStringToken(rxData));
01371 }
01372
01373
01374
01375 SopasBase::SopasCommand SopasBase::stringToSopasCommand(const std::string& cmdString)
01376 {
01377
01378 if (cmdString == "RN")
01379 {
01380 return RN;
01381 }
01382
01383
01384 else if (cmdString == "AN")
01385 {
01386 return AN;
01387 }
01388
01389 else if (cmdString == "SN")
01390 {
01391 return SN;
01392 }
01393
01394
01395 if (cmdString == "RI")
01396 {
01397 return RI;
01398 }
01399 else if (cmdString == "WI")
01400 {
01401 return WI;
01402 }
01403 else if (cmdString == "MI")
01404 {
01405 return MI;
01406 }
01407 else if (cmdString == "AI")
01408 {
01409 return AI;
01410 }
01411 else if (cmdString == "EI")
01412 {
01413 return EI;
01414 }
01415 else if (cmdString == "SI")
01416 {
01417 return SI;
01418 }
01419
01420
01421 else if (cmdString == "RA")
01422 {
01423 return RA;
01424 }
01425 else if (cmdString == "WA")
01426 {
01427 return WA;
01428 }
01429 else if (cmdString == "MA")
01430 {
01431 return MA;
01432 }
01433 else if (cmdString == "AA")
01434 {
01435 return AA;
01436 }
01437 else if (cmdString == "EA")
01438 {
01439 return EA;
01440 }
01441 else if (cmdString == "SA")
01442 {
01443 return SA;
01444 }
01445 else if (cmdString == "FA")
01446 {
01447 return FA;
01448 }
01449
01450 else
01451 {
01452 printError("SopasBase::stringToSopasCommand: Trying to resolve an unknown command: " + cmdString + ".");
01453 }
01454 return CMD_UNKNOWN;
01455 }
01456
01457
01458
01459
01460 std::string SopasBase::sopasCommandToString(SopasCommand cmd)
01461 {
01462
01463 if (cmd == RN)
01464 {
01465 return ("RN");
01466 }
01467
01468
01469 else if (cmd == AN)
01470 {
01471 return ("AN");
01472 }
01473
01474 else if (cmd == SN)
01475 {
01476 return ("SN");
01477 }
01478 if (cmd == RI)
01479 {
01480 return ("RI");
01481 }
01482 else if (cmd == WI)
01483 {
01484 return ("WI");
01485 }
01486 else if (cmd == MI)
01487 {
01488 return ("MI");
01489 }
01490 else if (cmd == AI)
01491 {
01492 return ("AI");
01493 }
01494 else if (cmd == EI)
01495 {
01496 return ("EI");
01497 }
01498 else if (cmd == SI)
01499 {
01500 return ("SI");
01501 }
01502
01503
01504 else if (cmd == RA)
01505 {
01506 return ("RA");
01507 }
01508 else if (cmd == WA)
01509 {
01510 return ("WA");
01511 }
01512 else if (cmd == MA)
01513 {
01514 return ("MA");
01515 }
01516 else if (cmd == AA)
01517 {
01518 return ("AA");
01519 }
01520 else if (cmd == EA)
01521 {
01522 return ("EA");
01523 }
01524 else if (cmd == SA)
01525 {
01526 return ("SA");
01527 }
01528 else if (cmd == FA)
01529 {
01530 return ("FA");
01531 }
01532 else
01533 {
01534 printError("SopasBase::sopasCommandToString: Trying to resolve an unknown command!");
01535 }
01536
01537 return "(unknown)";
01538 }
01539
01540
01541
01548 bool SopasBase::action_getScannerTypeAndVersion()
01549 {
01550
01551
01552 bool result = false;
01553
01554
01555 m_scannerName.empty();
01556 m_scannerVersion.empty();
01557
01558 SopasAnswer* answer = NULL;
01559 result = readVariable(INDEX_DEVICE_IDENT, answer);
01560
01561 if (result && answer != NULL && answer->isValid())
01562 {
01563
01564
01565 std::string colaaAnswer;
01566 switch (m_protocol)
01567 {
01568 case CoLa_A:
01569 colaaAnswer = std::string((char*)answer->getBuffer(), answer->size());
01570 colaA_decodeScannerTypeAndVersion(&colaaAnswer);
01571 break;
01572 case CoLa_B:
01573 colaB_decodeScannerTypeAndVersion(answer->getBuffer(), 0);
01574 break;
01575 }
01576
01577 if (!m_scannerName.empty() && !m_scannerVersion.empty())
01578 {
01579 result = true;
01580 }
01581 }
01582
01583 if (answer != NULL)
01584 {
01585 delete answer;
01586 }
01587
01588 return result;
01589 }
01590
01591
01592
01596 void SopasBase::colaA_decodeScannerTypeAndVersion(std::string* rxData)
01597 {
01598
01599
01600
01601
01602 UINT16 len = colaa::decodeUINT16(rxData);
01603
01604
01605 m_scannerName.clear();
01606 m_scannerName = rxData->substr(0, len);
01607
01608
01609 *rxData = rxData->substr(len + 1);
01610
01611
01612
01613
01614
01615 len = colaa::decodeUINT16(rxData);
01616
01617
01618 m_scannerVersion.clear();
01619 m_scannerVersion = rxData->substr(0, len);
01620 }
01621
01622
01623
01624
01625
01626 void SopasBase::colaB_decodeScannerTypeAndVersion(UINT8* buffer, UINT16 pos)
01627 {
01628 printInfoMessage("SopasBase::colaB_decodeScannerTypeAndVersion: Entering function.", m_beVerbose);
01629
01630 UINT16 fieldLength;
01631
01632
01633 fieldLength = colab::getIntegerFromBuffer<UINT16>(buffer, pos);
01634 m_scannerName = colab::getStringFromBuffer(buffer, pos, fieldLength);
01635
01636
01637 fieldLength = colab::getIntegerFromBuffer<UINT16>(buffer, pos);
01638 m_scannerVersion = colab::getStringFromBuffer(buffer, pos, fieldLength);
01639
01640 printInfoMessage("SopasBase::colaB_decodeScannerTypeAndVersion: scanner '" + m_scannerName + "', version '"
01641 + m_scannerVersion + "'.", m_beVerbose);
01642 }
01643
01644
01645
01646
01647
01648 bool SopasBase::invokeMethod(const std::string& methodeName, BYTE* parameters, UINT16 parametersLength, SopasAnswer*& answer)
01649 {
01650
01651 BYTE cmdBuffer[128];
01652 UINT16 cmdBufferLen = 0;
01653
01654 switch (m_protocol)
01655 {
01656 case CoLa_A:
01657 cmdBufferLen += colaa::addStringToBuffer(cmdBuffer, COMMAND_Invoke_Method_ByName);
01658 cmdBuffer[cmdBufferLen++] = ' ';
01659
01660 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[cmdBufferLen]), methodeName);
01661
01662 if (parametersLength > 0)
01663 {
01664 cmdBuffer[cmdBufferLen++] = ' ';
01665 }
01666 break;
01667 case CoLa_B:
01668 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, COMMAND_Invoke_Method_ByName);
01669
01670 colab::addIntegerToBuffer<UINT16>(cmdBuffer, cmdBufferLen, methodeName.size());
01671 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, methodeName);
01672 break;
01673 }
01674
01675 if (parametersLength > 0)
01676 {
01677
01678 memcpy(&cmdBuffer[cmdBufferLen], parameters, parametersLength);
01679 cmdBufferLen += parametersLength;
01680 }
01681
01682
01683 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
01684
01685
01686 bool result = receiveAnswer(AN, methodeName, 2000, answer);
01687
01688
01689 if (result == true)
01690 {
01691 printInfoMessage("SopasBase::invokeMethod: Calling of " + methodeName + " was successful.", m_beVerbose);
01692 }
01693 else
01694 {
01695 printWarning("SopasBase::invokeMethod: Calling of " + methodeName + " was NOT successful.");
01696 }
01697
01698 return result;
01699 }
01700
01701
01702
01703
01704
01705 bool SopasBase::invokeMethod(UINT16 index, BYTE* parameters, UINT16 parametersLength, SopasAnswer*& answer)
01706 {
01707
01708 BYTE cmdBuffer[128];
01709 UINT16 cmdBufferLen = 0;
01710
01711 switch (m_protocol)
01712 {
01713 case CoLa_A:
01714 printError("SopasBase::invokeMethod: Invoke method cola-a by index not supported.");
01715 return false;
01716 break;
01717 case CoLa_B:
01718 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, COMMAND_Invoke_Method_ByIndex);
01719
01720 colab::addIntegerToBuffer<UINT16>(cmdBuffer, cmdBufferLen, index);
01721 break;
01722 }
01723
01724 if (parametersLength > 0)
01725 {
01726
01727 memcpy(&cmdBuffer[cmdBufferLen], parameters, parametersLength);
01728 cmdBufferLen += parametersLength;
01729 }
01730
01731
01732 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
01733
01734
01735 bool result = receiveAnswer(AI, index, 2000, answer);
01736
01737
01738 if (result == true)
01739 {
01740 printInfoMessage("SopasBase::invokeMethod: Calling of method with index=" + ::toString(index) + " was successful.", m_beVerbose);
01741 }
01742 else
01743 {
01744 printWarning("SopasBase::invokeMethod: Calling of method with index=" + ::toString(index) + " was NOT successful.");
01745 }
01746
01747 return result;
01748 }
01749
01750
01751
01752
01753
01754 bool SopasBase::readVariable(const std::string& variableName, SopasAnswer*& answer)
01755 {
01756
01757 BYTE cmdBuffer[128];
01758 UINT16 cmdBufferLen = 0;
01759
01760 if (m_protocol == CoLa_A)
01761 {
01762 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[0]), COMMAND_Read_Variable_ByName);
01763 cmdBuffer[cmdBufferLen++] = ' ';
01764 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[cmdBufferLen]), variableName);
01765 }
01766 else
01767 {
01768
01769 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, COMMAND_Read_Variable_ByName);
01770 cmdBuffer[cmdBufferLen++] = ' ';
01771 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, variableName);
01772 }
01773
01774
01775 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
01776
01777
01778 bool result = receiveAnswer(RA, variableName, 2000, answer);
01779
01780 if (result)
01781 {
01782 printInfoMessage("SopasBase::readVariable: Answer to " + variableName + " received.", m_beVerbose);
01783 }
01784 else
01785 {
01786 printWarning("SopasBase::readVariable: Answer to " + variableName + " not successful.");
01787 }
01788
01789 return result;
01790 }
01791
01792
01793
01794
01795
01796 bool SopasBase::readVariable(UINT16 index, SopasAnswer*& answer)
01797 {
01798
01799 BYTE cmdBuffer[128];
01800 UINT16 cmdBufferLen = 0;
01801
01802 if (m_protocol == CoLa_A)
01803 {
01804 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[0]), COMMAND_Read_Variable_ByIndex);
01805 cmdBuffer[cmdBufferLen++] = ' ';
01806 cmdBufferLen += colaa::addUINT32ToBuffer(&(cmdBuffer[cmdBufferLen]), (UINT32)index);
01807 }
01808 else
01809 {
01810 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, COMMAND_Read_Variable_ByIndex);
01811 colab::addIntegerToBuffer<UINT16>(cmdBuffer, cmdBufferLen, index);
01812 }
01813
01814
01815 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
01816
01817
01818 bool result = receiveAnswer(RA, index, 2000, answer);
01819
01820 if (result)
01821 {
01822 printInfoMessage("SopasBase::readVariable: Answer to " + ::toString(index) + " received.", m_beVerbose);
01823 }
01824 else
01825 {
01826 printWarning("SopasBase::readVariable: Answer to " + ::toString(index) + " not successful.");
01827 }
01828
01829 return result;
01830 }
01831
01832
01833
01834 bool SopasBase::writeVariable(const std::string& variableName, BYTE* parameters, UINT16 parametersLength)
01835 {
01836 if (m_readOnlyMode)
01837 {
01838 printInfoMessage("SopasBase::writeVariable: ReadOnly Modus - ignore writing to variable '" +
01839 variableName + "'", m_beVerbose);
01840 return true;
01841 }
01842
01843
01844 BYTE cmdBuffer[128];
01845 UINT16 cmdBufferLen = 0;
01846
01847 if (m_protocol == CoLa_A)
01848 {
01849 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[0]), COMMAND_Write_Variable_ByName);
01850 cmdBuffer[cmdBufferLen++] = ' ';
01851 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[cmdBufferLen]), variableName);
01852 if (parametersLength > 0)
01853 {
01854 cmdBuffer[cmdBufferLen++] = ' ';
01855 }
01856 }
01857 else
01858 {
01859 printError("SopasBase::writeVariable: Write variable cola-b by Name: NOT IMPLEMENTED");
01860 return false;
01861
01862
01863
01864
01865
01866
01867 }
01868
01869
01870 if (parametersLength > 0)
01871 {
01872
01873 memcpy(&cmdBuffer[cmdBufferLen], parameters, parametersLength);
01874 cmdBufferLen += parametersLength;
01875 }
01876
01877
01878
01879 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
01880 SopasAnswer* answer = NULL;
01881
01882 bool result = receiveAnswer(WA, variableName, 2000, answer);
01883
01884 if (answer != NULL)
01885 {
01886 delete answer;
01887 }
01888
01889 if (result)
01890 {
01891 printInfoMessage("SopasBase::writeVariable: Answer to " + variableName + " received.", m_beVerbose);
01892 }
01893 else
01894 {
01895 printInfoMessage("SopasBase::writeVariable: Answer to " + variableName + " not successful.", m_beVerbose);
01896 }
01897
01898 return result;
01899 }
01900
01901
01902
01903
01904
01905 bool SopasBase::writeVariable(UINT16 variableIndex, BYTE* parameters, UINT16 parametersLength)
01906 {
01907 bool beVerboseHere = m_beVerbose;
01908
01909
01910 if (m_readOnlyMode == true)
01911 {
01912 printInfoMessage("SopasBase::writeVariable: ReadOnly Modus - ignore writing to variable index '" + ::toString(variableIndex) +
01913 "'", m_beVerbose);
01914 return true;
01915 }
01916
01917
01918 UINT32 cmdBufferLen = parametersLength + 4;
01919 BYTE* cmdBuffer = new BYTE[cmdBufferLen];
01920
01921
01922 colab::addStringToBuffer(&(cmdBuffer[0]), COMMAND_Write_Variable_ByIndex);
01923
01924
01925 BYTE* buffer = &(cmdBuffer[2]);
01926 memwrite_UINT16(buffer, variableIndex);
01927
01928
01929
01930
01931 memcpy(&(cmdBuffer[4]), parameters, parametersLength);
01932
01933
01934 printInfoMessage("SopasBase::writeVariable: Sending command buffer now (payload len=" + toString(parametersLength+4) + " bytes).", beVerboseHere);
01935 sendCommandBuffer(cmdBuffer, cmdBufferLen);
01936
01937 printInfoMessage("SopasBase::writeVariable: Command sent, waiting for reply...", beVerboseHere);
01938 SopasAnswer* answer = NULL;
01939
01940 bool result = receiveAnswer(WA, variableIndex, 2000, answer);
01941
01942 if (answer != NULL)
01943 {
01944 delete answer;
01945 }
01946 if (result)
01947 {
01948 printInfoMessage("SopasBase::writeVariable: Answer to " + toString(variableIndex) + " received.", beVerboseHere);
01949 }
01950 else
01951 {
01952 printWarning("SopasBase::writeVariable: Answer to " + toString(variableIndex) + " not successful!");
01953 }
01954
01955 printInfoMessage("SopasBase::writeVariable: All done, leaving.", beVerboseHere);
01956 return result;
01957 }
01958
01959
01960
01961 bool SopasBase::registerEvent(const std::string& eventName)
01962 {
01963 BYTE cmdBuffer[128];
01964 UINT16 cmdBufferLen = 0;
01965
01966 if (m_protocol == CoLa_A)
01967 {
01968 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[0]), COMMAND_Register_Event_ByName);
01969 cmdBuffer[cmdBufferLen++] = ' ';
01970 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[cmdBufferLen]), eventName);
01971 cmdBuffer[cmdBufferLen++] = ' ';
01972 cmdBuffer[cmdBufferLen++] = '1';
01973 }
01974 else
01975 {
01976
01977 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, COMMAND_Register_Event_ByName);
01978 cmdBuffer[cmdBufferLen++] = ' ';
01979 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, eventName);
01980 cmdBuffer[cmdBufferLen++] = ' ';
01981 colab::addIntegerToBuffer<UINT8>(cmdBuffer, cmdBufferLen, 1);
01982
01983
01984 }
01985
01986
01987 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
01988 SopasAnswer* answer = NULL;
01989
01990 bool result = receiveAnswer(EA, eventName, 2000, answer);
01991
01992
01993
01994 if (answer != NULL)
01995 {
01996 delete answer;
01997 }
01998 return result;
01999 }
02000
02001
02002
02003
02004
02005 bool SopasBase::registerEvent(UINT16 index)
02006 {
02007
02008 BYTE cmdBuffer[128];
02009 UINT16 cmdBufferLen = 0;
02010
02011 switch (m_protocol)
02012 {
02013 case CoLa_A:
02014 printError("SopasBase::register event cola-a by index not supported, aborting.");
02015
02016 return false;
02017
02018 break;
02019 case CoLa_B:
02020 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, COMMAND_Register_Event_ByIndex);
02021 colab::addIntegerToBuffer<UINT16>(cmdBuffer, cmdBufferLen, index);
02022 colab::addIntegerToBuffer<UINT8>(cmdBuffer, cmdBufferLen, 1);
02023 break;
02024 }
02025
02026
02027 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
02028
02029
02030 SopasAnswer* answer = NULL;
02031 bool result = receiveAnswer(EA, index, 2000, answer);
02032
02033
02034 if (answer != NULL)
02035 {
02036 delete answer;
02037 }
02038
02039
02040 if (result == true)
02041 {
02042 printInfoMessage("SopasBase::registerEvent: Calling of register with index=" + ::toString(index) + " was successful.", m_beVerbose);
02043 }
02044 else
02045 {
02046 printError("SopasBase::registerEvent: Calling of method with index=" + ::toString(index) + " was NOT successful.");
02047 }
02048 return result;
02049 }
02050
02051
02052
02053 bool SopasBase::unregisterEvent(UINT16 index)
02054 {
02055
02056 BYTE cmdBuffer[128];
02057 UINT16 cmdBufferLen = 0;
02058
02059 switch (m_protocol)
02060 {
02061 case CoLa_A:
02062 printError("SopasBase::unregisterEvent: Unregister event cola-a by index not supported.");
02063
02064 return false;
02065
02066 break;
02067 case CoLa_B:
02068 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, COMMAND_Register_Event_ByIndex);
02069 colab::addIntegerToBuffer<UINT16>(cmdBuffer, cmdBufferLen, index);
02070 colab::addIntegerToBuffer<UINT8>(cmdBuffer, cmdBufferLen, 0);
02071 break;
02072 }
02073
02074
02075 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
02076
02077
02078 SopasAnswer* answer = NULL;
02079 bool result = receiveAnswer(EA, index, 2000, answer);
02080
02081
02082 if (answer != NULL)
02083 {
02084 delete answer;
02085 }
02086
02087
02088 if (result == true)
02089 {
02090 printInfoMessage("SopasBase::calling of register with index=" + ::toString(index) + " was successful.", m_beVerbose);
02091 }
02092 else
02093 {
02094 printInfoMessage("SopasBase::calling of register with index=" + ::toString(index) + " was NOT successful.", m_beVerbose);
02095 }
02096
02097 return result;
02098 }
02099
02100
02101
02102 bool SopasBase::unregisterEvent(const std::string& eventName)
02103 {
02104 BYTE cmdBuffer[128];
02105 UINT16 cmdBufferLen = 0;
02106
02107 if (m_protocol == CoLa_A)
02108 {
02109 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[0]), COMMAND_Register_Event_ByName);
02110 cmdBuffer[cmdBufferLen++] = ' ';
02111 cmdBufferLen += colaa::addStringToBuffer(&(cmdBuffer[cmdBufferLen]), eventName);
02112 cmdBuffer[cmdBufferLen++] = ' ';
02113 cmdBuffer[cmdBufferLen++] = '0';
02114 }
02115 else
02116 {
02117
02118 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, COMMAND_Register_Event_ByName);
02119 cmdBuffer[cmdBufferLen++] = ' ';
02120 colab::addStringToBuffer(cmdBuffer, cmdBufferLen, eventName);
02121 cmdBuffer[cmdBufferLen++] = ' ';
02122 colab::addIntegerToBuffer<UINT8>(cmdBuffer, cmdBufferLen, 0);
02123
02124 }
02125
02126
02127 sendCommandBuffer(&(cmdBuffer[0]), cmdBufferLen);
02128 SopasAnswer* answer = NULL;
02129
02130 bool result = receiveAnswer(EA, eventName, 2000, answer);
02131
02132
02133
02134 if (answer != NULL)
02135 {
02136 delete answer;
02137 }
02138 return result;
02139 }
02140
02141
02142
02146 double SopasBase::makeAngleValid(double angle)
02147 {
02148 return ::normalizeRadians(angle);
02149 }
02150
02151
02152
02153
02154
02155
02156 SopasEventMessage::SopasEventMessage() :
02157 m_buffer(NULL), m_protocol(SopasBase::CoLa_A), m_frameLength(0), m_encoding(SopasBase::ByName)
02158 {
02159 }
02160
02161
02162
02163 SopasEventMessage::SopasEventMessage(BYTE* buffer, SopasBase::SopasProtocol protocol, UINT32 frameLength) :
02164 m_buffer(buffer), m_protocol(protocol), m_frameLength(frameLength), m_encoding(SopasBase::ByName)
02165 {
02166 detectEncoding();
02167 detectMessageType();
02168 }
02169
02170
02171
02172 UINT32 SopasEventMessage::getPayLoadLength() const
02173 {
02174 UINT32 payLoadLength = 0;
02175
02176 switch (m_protocol)
02177 {
02178 case SopasBase::CoLa_A:
02179 payLoadLength = m_frameLength - 2;
02180 break;
02181 case SopasBase::CoLa_B:
02182 payLoadLength = m_frameLength - 9;
02183 }
02184
02185 return payLoadLength;
02186 }
02187
02188
02189
02190 std::string SopasEventMessage::getCommandString() const
02191 {
02192 std::string commandString;
02193
02194 switch (m_protocol)
02195 {
02196 case SopasBase::CoLa_A:
02197 commandString = std::string((char*) &m_buffer[2], 2);
02198 break;
02199 case SopasBase::CoLa_B:
02200 commandString = std::string((char*) &m_buffer[9], 2);
02201 }
02202
02203 return commandString;
02204 }
02205
02206
02207
02208
02209
02210
02211
02212 BYTE* SopasEventMessage::getPayLoad()
02213 {
02214 BYTE* bufferPos = NULL;
02215
02216 switch (m_protocol)
02217 {
02218 case SopasBase::CoLa_A:
02219 bufferPos = &m_buffer[1];
02220 break;
02221 case SopasBase::CoLa_B:
02222 bufferPos = &m_buffer[8];
02223 break;
02224 }
02225
02226 return bufferPos;
02227 }
02228
02229
02230
02231 INT32 SopasEventMessage::getVariableIndex()
02232 {
02233 INT32 index = -1;
02234
02235 if (m_encoding != SopasBase::ByIndex)
02236 {
02237
02238 printWarning("SopasEventMessage::getVariableIndex: Encoding is not ByIndex, aborting!");
02239 return index;
02240 }
02241
02242 BYTE* bufferPos = &getPayLoad()[3];
02243 switch (m_protocol)
02244 {
02245 case SopasBase::CoLa_A:
02246 index = (INT32)(colaa::decodeUINT16(bufferPos));
02247 break;
02248 case SopasBase::CoLa_B:
02249 index = (INT32)(colab::decodeUINT16(bufferPos));
02250 break;
02251 default:
02252 printError("SopasEventMessage::getVariableIndex: Unknown protocol!");
02253 }
02254
02255 return index;
02256 }
02257
02258
02259
02260
02261 std::string SopasEventMessage::getVariableName()
02262 {
02263 std::string name;
02264 UINT32 i;
02265 BYTE* bufferPos;
02266
02267 if (m_encoding == SopasBase::ByName)
02268 {
02269 switch (m_protocol)
02270 {
02271 case SopasBase::CoLa_A:
02272 printError("SopasEventMessage::getVariableName: Protocol CoLa-A is not supported, aborting!");
02273 return "";
02274 break;
02275 case SopasBase::CoLa_B:
02276 bufferPos = &getPayLoad()[4];
02277 i = 4;
02278
02279
02280
02281
02282 while ((*bufferPos != ' ') && (i < getPayLoadLength()))
02283 {
02284 name += *bufferPos;
02285 bufferPos++;
02286 i++;
02287 }
02288 break;
02289 }
02290 }
02291
02292 return name;
02293 }
02294
02295
02296
02297
02298
02299 void SopasEventMessage::detectEncoding()
02300 {
02301
02302
02303 if (getPayLoad()[2] == 'I')
02304 {
02305 m_encoding = SopasBase::ByIndex;
02306 }
02307 }
02308
02309
02310
02311 void SopasEventMessage::detectMessageType()
02312 {
02313 std::string command = getCommandString();
02314
02315 if (command == SopasBase::COMMAND_Event_Acknowledge)
02316 {
02317 m_messageType = SopasBase::MSG_EVENT_ACKNOWLEDGE;
02318 }
02319 else if (command == SopasBase::COMMAND_Invoke_Method_Answer)
02320 {
02321 m_messageType = SopasBase::MSG_INVOKE_METHOD_ANSWER;
02322 }
02323 else if (command == SopasBase::COMMAND_Method_Result_Answer)
02324 {
02325 m_messageType = SopasBase::MSG_METHOD_RESULT_ANSWER;
02326 }
02327 else if (command == SopasBase::COMMAND_Send_Event_ByIndex || command == SopasBase::COMMAND_Send_Event_ByName)
02328 {
02329 m_messageType = SopasBase::MSG_SEND_EVENT;
02330 }
02331 else if (command == SopasBase::COMMAND_Read_Variable_Answer)
02332 {
02333 m_messageType = SopasBase::MSG_READ_VARIABLE_ANSWER;
02334 }
02335 else if (command == SopasBase::COMMAND_Write_Variable_Answer)
02336 {
02337 m_messageType = SopasBase::MSG_WRITE_VARIABLE_ANSWER;
02338 }
02339 else
02340 {
02341 m_messageType = SopasBase::MSG_UNKNOWN;
02342 }
02343 }
02344
02345 SopasAnswer::SopasAnswer(const BYTE* answer, UINT32 answerLength) : m_answerLength(answerLength)
02346 {
02347 if (answerLength > 0)
02348 {
02349 m_answerBuffer = new BYTE[m_answerLength];
02350 memcpy(m_answerBuffer, answer, answerLength);
02351 }
02352 else
02353 {
02354 m_answerBuffer = NULL;
02355 }
02356 }
02357
02358 SopasAnswer::~SopasAnswer()
02359 {
02360 if (m_answerBuffer != NULL)
02361 {
02362 delete[] m_answerBuffer;
02363 m_answerLength = 0;
02364 }
02365 }
02366
02367 }