00001
00002
00003
00004
00005
00006
00007
00008 #ifndef SOPASBASE_H
00009 #define SOPASBASE_H
00010
00011 #include "sick_scan/tcp/BasicDatatypes.hpp"
00012
00013 #include "sick_scan/tcp/interfaces/tcp.hpp"
00014
00015 #include "colaa.hpp"
00016 #include "colab.hpp"
00017 #include <map>
00018 #include "sick_scan/tcp/tools/Mutex.hpp"
00019
00020 namespace devices
00021 {
00022
00023 class SopasEventMessage;
00024 class SopasAnswer;
00025
00035 class SopasBase
00036 {
00037 public:
00038 static const std::string EVENTNAME_SUBSCRIBE_EVALCASES;
00039 static const std::string EVENTNAME_SUBSCRIBE_SCANS;
00040 static const std::string METHODNAME_LOGIN;
00041 static const std::string METHODNAME_LOGOUT;
00042 static const std::string METHODNAME_SET_SCANCONFIG;
00043 static const std::string METHODNAME_START_MEASURE;
00044 static const std::string METHODNAME_STOP_MEASURE;
00045 static const std::string VARIABLENAME_DEVICEIDENT;
00046 static const std::string VARIABLENAME_SCANCONFIG;
00047 static const std::string VARIABLENAME_DATAOUTPUTRANGE;
00048 static const std::string VARIABLENAME_SCANDATACONFIG;
00049
00050
00051 static const std::string COMMAND_Read_Variable_ByIndex;
00052 static const std::string COMMAND_Write_Variable_ByIndex;
00053 static const std::string COMMAND_Invoke_Method_ByIndex;
00054 static const std::string COMMAND_Method_Result_ByIndex;
00055 static const std::string COMMAND_Register_Event_ByIndex;
00056 static const std::string COMMAND_Send_Event_ByIndex;
00057
00058 static const std::string COMMAND_Read_Variable_Answer;
00059 static const std::string COMMAND_Write_Variable_Answer;
00060 static const std::string COMMAND_Invoke_Method_Answer;
00061 static const std::string COMMAND_Method_Result_Answer;
00062 static const std::string COMMAND_Register_Event_Answer;
00063 static const std::string COMMAND_Event_Acknowledge;
00064
00065 static const std::string COMMAND_Read_Variable_ByName;
00066 static const std::string COMMAND_Write_Variable_ByName;
00067 static const std::string COMMAND_Invoke_Method_ByName;
00068 static const std::string COMMAND_Method_Result_ByName;
00069 static const std::string COMMAND_Register_Event_ByName;
00070 static const std::string COMMAND_Send_Event_ByName;
00071
00072 static const UINT16 INDEX_DEVICE_IDENT;
00073
00074 enum SopasProtocol
00075 {
00076 CoLa_A,
00077 CoLa_B
00078 };
00079
00080 enum SopasEncoding
00081 {
00082 ByName,
00083 ByIndex
00084 };
00085
00087 enum SopasMessageType
00088 {
00089 MSG_UNKNOWN,
00090
00091
00092
00093
00094
00095 MSG_SEND_EVENT,
00096 MSG_READ_VARIABLE_ANSWER,
00097 MSG_WRITE_VARIABLE_ANSWER,
00098 MSG_INVOKE_METHOD_ANSWER,
00099 MSG_METHOD_RESULT_ANSWER,
00100 MSG_REGISTER_EVENT_ANSWER,
00101 MSG_EVENT_ACKNOWLEDGE,
00102 MSG_ERROR
00104 };
00105
00106 typedef void (*DecoderFunction)(SopasEventMessage& frame);
00107
00109 SopasBase();
00110
00112 virtual ~SopasBase();
00113
00115
00127 virtual bool init(SopasProtocol protocol,
00128 std::string ipAddress,
00129 UINT16 portNumber,
00130 bool weWantScanData,
00131 bool weWantFieldData,
00132 bool readOnlyMode,
00133 Tcp::DisconnectFunction disconnectFunction,
00134 void* obj);
00135
00137 bool connect();
00138
00140 bool isConnected();
00141
00149 bool disconnect();
00150
00156 bool action_getScannerTypeAndVersion();
00157
00158
00159 void setReadOnlyMode(bool mode);
00160
00161 bool isReadOnly();
00162
00171 bool invokeMethod(const std::string& methodeName, BYTE* parameters, UINT16 parametersLength, SopasAnswer*& answer);
00172
00181 bool invokeMethod(UINT16 index, BYTE* parameters, UINT16 parametersLength, SopasAnswer*& answer);
00182
00189 bool readVariable(const std::string& variableName, SopasAnswer*& answer);
00190
00197 bool readVariable(UINT16 index, SopasAnswer*& answer);
00198
00206 bool writeVariable(const std::string& variableName, BYTE* parameters, UINT16 parametersLength);
00207
00215 bool writeVariable(UINT16 index, BYTE* parameters, UINT16 parametersLength);
00216
00222 bool registerEvent(const std::string& eventName);
00223
00229 bool registerEvent(UINT16 index);
00230
00236 bool unregisterEvent(const std::string& eventName);
00237
00243 bool unregisterEvent(UINT16 index);
00244
00250 void setEventCallbackFunction(DecoderFunction decoderFunction, const std::string& eventName)
00251 {
00252 m_decoderFunctionMapByName[eventName] = decoderFunction;
00253 }
00254
00260 void setEventCallbackFunction(DecoderFunction decoderFunction, UINT16 eventIndex)
00261 {
00262 m_decoderFunctionMapByIndex[eventIndex] = decoderFunction;
00263 }
00264
00265
00266 double makeAngleValid(double angle);
00267
00268 const std::string& getScannerName() const { return m_scannerName; }
00269 const std::string& getScannerVersion() const { return m_scannerVersion; }
00270
00271
00272 static std::string convertSopasErrorCodeToText(UINT16 errorCode);
00273
00274 protected:
00275
00276 enum SopasCommand
00277 {
00278 CMD_UNKNOWN = 0,
00279 RI = 1,
00280 WI = 2,
00281 MI = 3,
00282 AI = 4,
00283 EI = 5,
00284 SI = 6,
00285 RA = 7,
00286 WA = 8,
00287 MA = 9,
00288 AA = 10,
00289 EA = 11,
00290 SA = 12,
00291 RN = 20,
00292 AN = 21,
00293 SN = 22,
00294 FA = 50
00296 };
00297
00298 enum State
00299 {
00301 CONSTRUCTED
00304 ,
00305 CONNECTED
00308
00309 };
00310
00321 bool receiveAnswer(SopasCommand cmd, std::string name, UINT32 timeout, SopasAnswer*& answer);
00322 bool receiveAnswer_CoLa_A(SopasCommand cmd, std::string name, UINT32 timeout, SopasAnswer*& answer );
00323 bool receiveAnswer_CoLa_B(SopasCommand cmd, std::string name, UINT32 timeout, SopasAnswer*& answer );
00324 bool receiveAnswer(SopasCommand cmd, UINT16 index, UINT32 timeout, SopasAnswer*& answer );
00325 bool receiveAnswer_CoLa_A(SopasCommand cmd, UINT16 index, UINT32 timeout, SopasAnswer*& answer);
00326 bool receiveAnswer_CoLa_B(SopasCommand cmd, UINT16 index, UINT32 timeout, SopasAnswer*& answer);
00327
00333 void sendCommandBuffer(UINT8* buffer, UINT16 len);
00334
00335 SopasCommand colaA_decodeCommand(std::string* rxData);
00336
00338 SopasCommand stringToSopasCommand(const std::string& cmdString);
00339 std::string sopasCommandToString(SopasCommand cmd);
00340
00341 protected:
00342
00343 virtual void evalCaseResultDecoder(SopasEventMessage& msg) = 0;
00344 virtual void scanDataDecoder(SopasEventMessage& msg) = 0;
00345
00346 bool m_scanEventIsRegistered;
00347 bool m_fieldEventIsRegistered;
00348 bool m_weWantScanData;
00349 bool m_weWantFieldData;
00350
00352 State m_state;
00353 std::string m_scannerName;
00354 std::string m_scannerVersion;
00355
00356 bool m_beVerbose;
00357
00358 bool m_isLoggedIn;
00359
00360 private:
00361
00362 bool openTcpConnection();
00363 void closeTcpConnection();
00364
00366 static void readCallbackFunctionS(void* obj, UINT8* buffer, UINT32& numOfBytes);
00367 void readCallbackFunction(UINT8* buffer, UINT32& numOfBytes);
00368
00370 SopasEventMessage findFrameInReceiveBuffer();
00371
00373 void processFrame(SopasEventMessage& frame);
00374 void processFrame_CoLa_A(SopasEventMessage& frame);
00375 void processFrame_CoLa_B(SopasEventMessage& frame);
00376 void copyFrameToResposeBuffer(UINT32 frameLength);
00377 void removeFrameFromReceiveBuffer(UINT32 frameLength);
00378
00379
00380 SopasProtocol m_protocol;
00381 SopasEncoding m_encoding;
00382 void colaA_decodeScannerTypeAndVersion(std::string* rxData);
00383 void colaB_decodeScannerTypeAndVersion(UINT8* buffer, UINT16 pos);
00384
00385 private:
00386 typedef std::map<std::string, DecoderFunction> DecoderFunctionMapByName;
00387 typedef std::map<UINT16, DecoderFunction> DecoderFunctionMapByIndex;
00388 DecoderFunctionMapByName m_decoderFunctionMapByName;
00389 DecoderFunctionMapByIndex m_decoderFunctionMapByIndex;
00390
00391
00392
00393
00394 typedef std::map<UINT16, std::string> IndexToNameMap;
00395 IndexToNameMap m_indexToNameMap;
00396
00397
00398 UINT32 m_numberOfBytesInResponseBuffer;
00399 UINT8 m_responseBuffer[1024];
00400 Mutex m_receiveDataMutex;
00401
00402
00403 UINT32 m_numberOfBytesInReceiveBuffer;
00404 UINT8 m_receiveBuffer[25000];
00405
00406
00407 Tcp m_tcp;
00408 std::string m_ipAddress;
00409 UINT16 m_portNumber;
00410
00411 bool m_readOnlyMode;
00412 };
00413
00414
00416 class SopasEventMessage
00417 {
00418 public:
00420 SopasEventMessage();
00421
00423 ~SopasEventMessage() {}
00424
00432 SopasEventMessage(BYTE* buffer, SopasBase::SopasProtocol protocol, UINT32 frameLength);
00433
00434 SopasBase::SopasProtocol getProtocolType() const
00435 {
00436 return m_protocol;
00437 }
00438
00439 SopasBase::SopasEncoding getEncodingType() const
00440 {
00441 return m_encoding;
00442 }
00443
00444 SopasBase::SopasMessageType getMessageType() const
00445 {
00446 return m_messageType;
00447 }
00448
00449 UINT32 size() const
00450 {
00451 return m_frameLength;
00452 }
00453
00455 UINT32 getPayLoadLength() const;
00456
00457 std::string getCommandString() const;
00458
00460 BYTE* getPayLoad();
00461
00463 INT32 getVariableIndex();
00464
00466 std::string getVariableName();
00467
00468 bool isValid() const { return (m_buffer != NULL); }
00469
00470 private:
00471 void detectEncoding();
00472
00473 void detectMessageType();
00474
00475 private:
00476 BYTE* m_buffer;
00477 SopasBase::SopasProtocol m_protocol;
00478 UINT32 m_frameLength;
00479 SopasBase::SopasEncoding m_encoding;
00480 SopasBase::SopasMessageType m_messageType;
00481 };
00482
00484 class SopasAnswer
00485 {
00486 public:
00488 SopasAnswer(const BYTE* answer, UINT32 answerLength);
00489
00491 ~SopasAnswer();
00492
00493 BYTE* getBuffer() { return m_answerBuffer; }
00494
00495 UINT32 size() { return m_answerLength; }
00496
00497 bool isValid() { return (m_answerBuffer != NULL); }
00498
00499 private:
00500 UINT32 m_answerLength;
00501 BYTE* m_answerBuffer;
00502 };
00503
00504 }
00505
00506 #endif // SOPASBASE_H