00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 00002 00003 // -- BEGIN LICENSE BLOCK ---------------------------------------------- 00004 00024 // -- END LICENSE BLOCK ------------------------------------------------ 00025 00026 //---------------------------------------------------------------------- 00033 //---------------------------------------------------------------------- 00034 00035 #include <sick_safetyscanners/cola2/Cola2Session.h> 00036 00037 namespace sick { 00038 namespace cola2 { 00039 00040 Cola2Session::Cola2Session(const std::shared_ptr<communication::AsyncTCPClient>& async_tcp_client) 00041 : m_async_tcp_client_ptr(async_tcp_client) 00042 , m_session_id(0) 00043 , m_last_request_id(0) 00044 { 00045 m_async_tcp_client_ptr->setPacketHandler(boost::bind(&Cola2Session::processPacket, this, _1)); 00046 m_packet_merger_ptr = std::make_shared<sick::data_processing::TCPPacketMerger>(); 00047 m_tcp_parser_ptr = std::make_shared<sick::data_processing::ParseTCPPacket>(); 00048 } 00049 00050 bool Cola2Session::open() 00051 { 00052 CommandPtr command_ptr = std::make_shared<CreateSession>(boost::ref(*this)); 00053 return executeCommand(command_ptr); 00054 } 00055 00056 bool Cola2Session::close() 00057 { 00058 CommandPtr command_ptr = std::make_shared<CloseSession>(boost::ref(*this)); 00059 return executeCommand(command_ptr); 00060 } 00061 00062 void Cola2Session::doDisconnect() 00063 { 00064 m_async_tcp_client_ptr->doDisconnect(); 00065 } 00066 00067 bool Cola2Session::executeCommand(const CommandPtr& command) 00068 { 00069 addCommand(command->getRequestID(), command); 00070 sendTelegramAndListenForAnswer(command); 00071 return true; 00072 } 00073 00074 bool Cola2Session::sendTelegramAndListenForAnswer(const CommandPtr& command) 00075 { 00076 command->lockExecutionMutex(); // lock 00077 sick::datastructure::PacketBuffer::VectorBuffer telegram; 00078 command->constructTelegram(telegram); 00079 m_async_tcp_client_ptr->doSendAndReceive(telegram); 00080 command->waitForCompletion(); // scooped locked to wait, unlocked on data processing 00081 return true; 00082 } 00083 00084 00085 uint32_t Cola2Session::getSessionID() const 00086 { 00087 return m_session_id; 00088 } 00089 00090 void Cola2Session::setSessionID(const uint32_t& session_id) 00091 { 00092 m_session_id = session_id; 00093 } 00094 00095 void Cola2Session::processPacket(const datastructure::PacketBuffer& packet) 00096 { 00097 addPacketToMerger(packet); 00098 if (!checkIfPacketIsCompleteAndOtherwiseListenForMorePackets()) 00099 return; 00100 sick::datastructure::PacketBuffer deployedPacket = m_packet_merger_ptr->getDeployedPacketBuffer(); 00101 startProcessingAndRemovePendingCommandAfterwards(deployedPacket); 00102 } 00103 00104 bool Cola2Session::addPacketToMerger(const sick::datastructure::PacketBuffer& packet) 00105 { 00106 if (m_packet_merger_ptr->isEmpty() || m_packet_merger_ptr->isComplete()) 00107 { 00108 m_packet_merger_ptr->setTargetSize(m_tcp_parser_ptr->getExpectedPacketLength(packet)); 00109 } 00110 m_packet_merger_ptr->addTCPPacket(packet); 00111 return true; 00112 } 00113 00114 bool Cola2Session::checkIfPacketIsCompleteAndOtherwiseListenForMorePackets() 00115 { 00116 if (!m_packet_merger_ptr->isComplete()) 00117 { 00118 m_async_tcp_client_ptr->initiateReceive(); 00119 return false; 00120 } 00121 return true; 00122 } 00123 00124 00125 bool Cola2Session::startProcessingAndRemovePendingCommandAfterwards( 00126 const sick::datastructure::PacketBuffer& packet) 00127 { 00128 uint16_t requestID = m_tcp_parser_ptr->getRequestID(packet); 00129 CommandPtr pendingCommand; 00130 if (findCommand(requestID, pendingCommand)) 00131 { 00132 pendingCommand->processReplyBase(packet.getBuffer()); 00133 removeCommand(requestID); 00134 } 00135 return true; 00136 } 00137 00138 bool Cola2Session::addCommand(const uint16_t& request_id, const CommandPtr& command) 00139 { 00140 if (m_pending_commands_map.find(request_id) != m_pending_commands_map.end()) 00141 { 00142 return false; 00143 } 00144 m_pending_commands_map[request_id] = command; 00145 return true; 00146 } 00147 00148 bool Cola2Session::findCommand(const uint16_t& request_id, CommandPtr& command) 00149 { 00150 if (m_pending_commands_map.find(request_id) == m_pending_commands_map.end()) 00151 { 00152 return false; 00153 } 00154 command = m_pending_commands_map[request_id]; 00155 return true; 00156 } 00157 00158 bool Cola2Session::removeCommand(const uint16_t& request_id) 00159 { 00160 auto it = m_pending_commands_map.find(request_id); 00161 if (it == m_pending_commands_map.end()) 00162 { 00163 return false; 00164 } 00165 m_pending_commands_map.erase(it); 00166 return true; 00167 } 00168 00169 uint16_t Cola2Session::getNextRequestID() 00170 { 00171 if (m_last_request_id == std::numeric_limits<uint16_t>::max()) 00172 { 00173 m_last_request_id = 0; 00174 } 00175 return ++m_last_request_id; 00176 } 00177 00178 } // namespace cola2 00179 } // namespace sick