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