bool EosOsc::SendPacket(EosTcp &tcp, char *data, size_t size) { bool success = false; if(data && size!=0) { long header = static_cast<long>(size); size_t totalSize = (size + sizeof(header)); if(m_SendPacket.data && m_SendPacket.size<totalSize) { delete[] m_SendPacket.data; m_SendPacket.data = 0; } if( !m_SendPacket.data ) { m_SendPacket.size = totalSize; m_SendPacket.data = new char[m_SendPacket.size]; } memcpy(m_SendPacket.data, &header, sizeof(header)); OSCArgument::Swap32(m_SendPacket.data); memcpy(&m_SendPacket.data[sizeof(header)], data, size); if( tcp.Send(*m_pLog,m_SendPacket.data,totalSize) ) { char text[128]; sprintf(text, "Sent Osc Packet [%d]", static_cast<int>(totalSize)); m_pLog->AddDebug(text); m_Parser.PrintPacket(*this, data, size); success = true; } delete[] data; } return success; }
void EosOsc::Recv(EosTcp &tcp, unsigned int timeoutMS, CMD_Q &cmdQ) { size_t size; const char *buf = tcp.Recv(*m_pLog, timeoutMS, size); if(buf && size!=0) { // append incoming data if( !m_InputBuffer.data ) { m_InputBuffer.capacity = m_InputBuffer.size = size; m_InputBuffer.data = new char[m_InputBuffer.capacity]; memcpy(m_InputBuffer.data, buf, size); } else { size_t requiredCapacity = (m_InputBuffer.size + size); if(m_InputBuffer.capacity < requiredCapacity) { // expand char *prevBuf = m_InputBuffer.data; size_t prevSize = m_InputBuffer.size; m_InputBuffer.capacity = m_InputBuffer.size = requiredCapacity; m_InputBuffer.data = new char[m_InputBuffer.capacity]; memcpy(m_InputBuffer.data, prevBuf, prevSize); memcpy(&m_InputBuffer.data[prevSize], buf, size); delete[] prevBuf; } else { // fits memcpy(&m_InputBuffer.data[m_InputBuffer.size], buf, size); m_InputBuffer.size += size; } } // do we have a complete osc packet? long oscPacketLen = 0; while(m_InputBuffer.data && m_InputBuffer.size>=sizeof(oscPacketLen)) { memcpy(&oscPacketLen, m_InputBuffer.data, sizeof(oscPacketLen)); OSCArgument::Swap32(&oscPacketLen); if(oscPacketLen < 0) oscPacketLen = 0; size_t totalSize = (sizeof(oscPacketLen) + static_cast<size_t>(oscPacketLen)); if(oscPacketLen>0 && m_InputBuffer.size>=totalSize) { // yup, great success char *oscData = &m_InputBuffer.data[sizeof(oscPacketLen)]; char text[128]; sprintf(text, "Received Osc Packet [%d]", static_cast<int>(oscPacketLen)); m_pLog->AddDebug(text); m_Parser.PrintPacket(*this, oscData, oscPacketLen); sCommand *cmd = new sCommand; cmd->buf = new char[oscPacketLen]; memcpy(cmd->buf, oscData, oscPacketLen); // find osc path null terminator for(long i=0; i<oscPacketLen; i++) { if(cmd->buf[i] == 0) { cmd->path = cmd->buf; cmd->argCount = 0xffffffff; cmd->args = OSCArgument::GetArgs(cmd->buf , static_cast<size_t>(oscPacketLen), cmd->argCount); break; } } cmdQ.push(cmd); // shift away processed data m_InputBuffer.size -= totalSize; if(m_InputBuffer.size != 0) memcpy(m_InputBuffer.data, &m_InputBuffer.data[totalSize], m_InputBuffer.size); } else { // awaiting more data break; } } } }
void EosTcpClientThread::run() { QString msg = QString("tcp client %1:%2 thread started").arg(m_Ip).arg(m_Port); m_PrivateLog.AddInfo( msg.toUtf8().constData() ); UpdateLog(); const size_t ReconnectDelay = 5000; EosTimer reconnectTimer; // outer loop for auto-reconnect while( m_Run ) { EosTcp *tcp = EosTcp::Create(); if( tcp->Initialize(m_PrivateLog,m_Ip.toUtf8().constData(),m_Port) ) { OSCParser parser; parser.SetRoot(new OSCHandler(*this)); std::string inPrefix = QString("TCPIN [%1:%2] ").arg(m_Ip).arg(m_Port).toUtf8().constData(); std::string outPrefix = QString("TCPOUT [%1:%2] ").arg(m_Ip).arg(m_Port).toUtf8().constData(); sPacket packet; // connect while(m_Run && tcp->GetConnectState()==EosTcp::CONNECT_IN_PROGRESS) { tcp->Tick(m_PrivateLog); UpdateLog(); msleep(10); } UpdateLog(); // send/recv while connected if(m_Run && tcp->GetConnectState()==EosTcp::CONNECT_CONNECTED) { m_Mutex.lock(); m_NetEventQ.push_back(NET_EVENT_CONNECTED); m_Mutex.unlock(); PACKET_Q sendQ; OSCStream oscStream(m_FrameMode); do { size_t len = 0; const char *data = tcp->Recv(m_PrivateLog, 100, len); oscStream.Add(data, len); while( m_Run ) { packet.data = oscStream.GetNextFrame(packet.size); if(packet.data && packet.size!=0) { m_Prefix = inPrefix; m_LogMsgType = EosLog::LOG_MSG_TYPE_RECV; parser.PrintPacket(*this, packet.data, packet.size); parser.ProcessPacket(*this, packet.data, packet.size); delete[] packet.data; } else break; } msleep(1); m_Mutex.lock(); m_SendQ.swap(sendQ); m_Mutex.unlock(); sPacket framedPacket; for(PACKET_Q::iterator i=sendQ.begin(); m_Run && i!=sendQ.end(); i++) { framedPacket.size = i->size; framedPacket.data = OSCStream::CreateFrame(m_FrameMode, i->data, framedPacket.size); if(framedPacket.data && framedPacket.size!=0) { if( tcp->Send(m_PrivateLog,framedPacket.data,framedPacket.size) ) { m_Prefix = outPrefix; m_LogMsgType = EosLog::LOG_MSG_TYPE_SEND; parser.PrintPacket(*this, i->data, i->size); } delete[] framedPacket.data; } delete[] i->data; } sendQ.clear(); UpdateLog(); msleep(1); } while(m_Run && tcp->GetConnectState()==EosTcp::CONNECT_CONNECTED); m_Mutex.lock(); m_NetEventQ.push_back(NET_EVENT_DISCONNECTED); m_Mutex.unlock(); } } delete tcp; if( m_Run ) { msg = QString("tcp client %1:%2 reconnecting in %3...").arg(m_Ip).arg(m_Port).arg(ReconnectDelay/1000); m_PrivateLog.AddInfo( msg.toUtf8().constData() ); UpdateLog(); } reconnectTimer.Start(); while(m_Run && !reconnectTimer.GetExpired(ReconnectDelay)) msleep(10); } msg = QString("tcp client %1:%2 thread ended").arg(m_Ip).arg(m_Port); m_PrivateLog.AddInfo( msg.toUtf8().constData() ); UpdateLog(); }