diff --git a/.gitignore b/.gitignore index 96374c4..f765e4f 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,13 @@ $RECYCLE.BIN/ Network Trash Folder Temporary Items .apdisk + +# ========================== +# Linux +# ========================== + +#Object code generated during test compilations +*.o + +#qmake path +.qmake.stash diff --git a/EosSyncLib/EosOsc.cpp b/EosSyncLib/EosOsc.cpp index db869ce..51587e3 100644 --- a/EosSyncLib/EosOsc.cpp +++ b/EosSyncLib/EosOsc.cpp @@ -195,7 +195,7 @@ void EosOsc::Recv(EosTcp &tcp, unsigned int timeoutMS, CMD_Q &cmdQ) // shift away processed data m_InputBuffer.size -= totalSize; if(m_InputBuffer.size != 0) - memcpy(m_InputBuffer.data, &m_InputBuffer.data[totalSize], m_InputBuffer.size); + memmove(m_InputBuffer.data, &m_InputBuffer.data[totalSize], m_InputBuffer.size); } else { diff --git a/EosSyncLib/EosSyncLib.pro b/EosSyncLib/EosSyncLib.pro new file mode 100644 index 0000000..8c10e6f --- /dev/null +++ b/EosSyncLib/EosSyncLib.pro @@ -0,0 +1,43 @@ +TEMPLATE = app +TARGET = ../../bin/EosSyncTest +INCLUDEPATH += . +CONFIG += debug + +# Input +HEADERS += EosLog.h \ + EosOsc.h \ + EosSyncLib.h \ + EosTcp.h \ + EosTimer.h \ + EosUdp.h \ + OSCParser.h +SOURCES += EosLog.cpp \ + EosOsc.cpp \ + EosSyncLib.cpp \ + EosTcp.cpp \ + EosTimer.cpp \ + EosUdp.cpp \ + main.cpp \ + OSCParser.cpp + +win32 { + HEADERS += EosTcp_Win.h \ + EosUdp_Win.h + SOURCES += EosTcp_Win.cpp \ + EosUdp_Win.cpp +} + +macx { + HEADERS += EosTcp_Mac.h \ + EosUdp_Mac.h + SOURCES += EosTcp_Mac.cpp \ + EosUdp_Mac.cpp +} + +unix { + HEADERS += EosTcp_Nix.h \ + EosUdp_Nix.h + SOURCES += EosTcp_Nix.cpp \ + EosUdp_Nix.cpp +} + diff --git a/EosSyncLib/EosTcp.cpp b/EosSyncLib/EosTcp.cpp index 932b261..996cf75 100644 --- a/EosSyncLib/EosTcp.cpp +++ b/EosSyncLib/EosTcp.cpp @@ -23,8 +23,10 @@ #ifdef WIN32 #include "EosTcp_Win.h" -#else +#elif defined TARGET_OS_MAC #include "EosTcp_Mac.h" +#elif defined __linux__ + #include "EosTcp_Nix.h" #endif //////////////////////////////////////////////////////////////////////////////// @@ -43,7 +45,7 @@ void EosTcp::SetLogPrefix(const char *name, const char *ip, unsigned short port, else logPrefix.clear(); - size_t maxLen = strlen("255.255.255.255"); + size_t maxLen = std::string("255.255.255.255").length(); if(logPrefix.size() > maxLen) logPrefix.resize(maxLen); @@ -71,8 +73,10 @@ EosTcp* EosTcp::Create() { #ifdef WIN32 return (new EosTcp_Win()); -#else +#elif defined TARGET_OS_MAC return (new EosTcp_Mac()); +#elif defined __linux__ + return (new EosTcp_Nix()); #endif } @@ -89,8 +93,10 @@ EosTcpServer* EosTcpServer::Create() { #ifdef WIN32 return (new EosTcpServer_Win()); -#else +#elif defined TARGET_OS_MAC return (new EosTcpServer_Mac()); +#elif defined __linux__ + return (new EosTcpServer_Nix()); #endif } diff --git a/EosSyncLib/EosTcp_Nix.cpp b/EosSyncLib/EosTcp_Nix.cpp new file mode 100644 index 0000000..5a60c8b --- /dev/null +++ b/EosSyncLib/EosTcp_Nix.cpp @@ -0,0 +1,562 @@ +// Copyright (c) 2015 Electronic Theatre Controls, Inc., http://www.etcconnect.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "EosTcp_Nix.h" +#include "EosLog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RECV_BUF_SIZE 1024 + +//////////////////////////////////////////////////////////////////////////////// + +EosTcp_Nix::EosTcp_Nix() + : m_Socket(-1) + , m_RecvBuf(0) +{ +} + +//////////////////////////////////////////////////////////////////////////////// + +EosTcp_Nix::~EosTcp_Nix() +{ + Shutdown(); +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosTcp_Nix::Initialize(EosLog &log, const char *ip, unsigned short port) +{ + if(m_Socket == -1) + { + SetLogPrefix("tcp client", ip, port, m_LogPrefix); + + if(ip && *ip) + { + m_Socket = socket(AF_INET, SOCK_STREAM, 0); + if(m_Socket != -1) + { + sockaddr_in addr; + std::memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(ip); + addr.sin_port = htons(port); + + // ignore SIGPIPE + + signal(SIGPIPE, SIG_IGN); + + // temporarily make socket non-blocking during connect + SetSocketBlocking(log, m_LogPrefix, m_Socket, false); + + if(connect(m_Socket,reinterpret_cast(&addr),static_cast(sizeof(addr))) == 0) + { + char text[256]; + sprintf(text, "%s connected", GetLogPrefix(m_LogPrefix)); + log.AddInfo(text); + m_ConnectState = CONNECT_CONNECTED; + SetSocketBlocking(log, m_LogPrefix, m_Socket, true); + return true; + } + else if(errno == EINPROGRESS) + { + char text[256]; + sprintf(text, "%s connecting...", GetLogPrefix(m_LogPrefix)); + log.AddInfo(text); + m_ConnectState = CONNECT_IN_PROGRESS; + return true; + } + else + { + char text[256]; + sprintf(text, "%s connect failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + close(m_Socket); + m_Socket = -1; + } + } + else + { + char text[256]; + sprintf(text, "%s socket failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s initialize failed, invalid arguments", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s initialize failed, already initialized", GetLogPrefix(m_LogPrefix)); + log.AddWarning(text); + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosTcp_Nix::InitializeAccepted(EosLog &log, void *pSocket) +{ + if(m_Socket == -1) + { + if( pSocket ) + m_Socket = *static_cast(pSocket); + + if(m_Socket != -1) + { + m_ConnectState = CONNECT_CONNECTED; + } + else + { + char text[256]; + sprintf(text, "%s initialize accepted failed, invalid arguments", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s initialize accepted failed, already initialized", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + + return (m_Socket != -1); +} + +//////////////////////////////////////////////////////////////////////////////// + +void EosTcp_Nix::Shutdown() +{ + if(m_Socket != -1) + { + close(m_Socket); + m_Socket = -1; + } + + if( m_RecvBuf ) + { + delete[] m_RecvBuf; + m_RecvBuf = 0; + } + + m_ConnectState = CONNECT_NOT_CONNECTED; +} + +//////////////////////////////////////////////////////////////////////////////// + +void EosTcp_Nix::Tick(EosLog &log) +{ + if(m_Socket != -1) + { + if(m_ConnectState == CONNECT_IN_PROGRESS) + { + fd_set writefds; + FD_ZERO(&writefds); + FD_SET(m_Socket, &writefds); + + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 1000; + + int result = select(m_Socket+1, 0, &writefds, 0, &timeout); + if(result > 0) + { + int optValue = 0; + socklen_t optLen = sizeof(optValue); + if(getsockopt(m_Socket,SOL_SOCKET,SO_ERROR,&optValue,&optLen) == 0) + { + if(optValue == 0) + { + char text[256]; + sprintf(text, "%s connected", GetLogPrefix(m_LogPrefix)); + log.AddInfo(text); + m_ConnectState = CONNECT_CONNECTED; + SetSocketBlocking(log, m_LogPrefix, m_Socket, true); + } + else + { + char text[256]; + sprintf(text, "%s connect failed with error %d", GetLogPrefix(m_LogPrefix), optValue); + log.AddError(text); + Shutdown(); + } + } + else + { + char text[256]; + sprintf(text, "%s getsockopt failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + Shutdown(); + } + } + else if(result < 0) + { + char text[256]; + sprintf(text, "%s connect wait failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + Shutdown(); + } + } + } + else + { + char text[256]; + sprintf(text, "%s tick failed, not initialized", GetLogPrefix(m_LogPrefix)); + log.AddWarning(text); + } +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosTcp_Nix::Send(EosLog &log, const char *data, size_t size) +{ + if(m_Socket != -1) + { + if(m_ConnectState == CONNECT_CONNECTED) + { + ssize_t result = send(m_Socket, data, size, 0); + if(result == -1) + { + char text[256]; + sprintf(text, "%s send failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + m_ConnectState = CONNECT_NOT_CONNECTED; + } + else if(static_cast(result) != size) + { + char text[256]; + sprintf(text, "%s send truncated %d of %d", GetLogPrefix(m_LogPrefix), static_cast(result), static_cast(size)); + log.AddError(text); + m_ConnectState = CONNECT_NOT_CONNECTED; + } + else + return true; + } + else + { + char text[256]; + sprintf(text, "%s send failed, not connected", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s send failed, not initialized", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// + +const char* EosTcp_Nix::Recv(EosLog &log, unsigned int timeoutMS, size_t &size) +{ + if(m_Socket != -1) + { + if(m_ConnectState == CONNECT_CONNECTED) + { + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(m_Socket, &readfds); + + timeval timeout; + timeout.tv_sec = timeoutMS/1000; + timeout.tv_usec = ((timeoutMS - timeoutMS/1000) * 1000); + + int result = select(m_Socket+1, &readfds, 0, 0, &timeout); + if(result > 0) + { + if( !m_RecvBuf ) + m_RecvBuf = new char[RECV_BUF_SIZE]; + + result = recv(m_Socket, m_RecvBuf, RECV_BUF_SIZE, 0); + if(result == -1) + { + char text[256]; + sprintf(text, "%s recv failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + m_ConnectState = CONNECT_NOT_CONNECTED; + } + else if(result > 0) + { + size = static_cast(result); + return m_RecvBuf; + } + } + else if(result < 0) + { + char text[256]; + sprintf(text, "%s select failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + m_ConnectState = CONNECT_NOT_CONNECTED; + } + } + else + { + char text[256]; + sprintf(text, "%s recv failed, not connected", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s recv failed, not initialized", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosTcp_Nix::SetSocketBlocking(EosLog &log, const std::string &logPrefix, int socket, bool b) +{ + if(socket != -1) + { + int flags = fcntl(socket, F_GETFL, 0); + if(flags == -1) + { + char text[256]; + sprintf(text, "%s fnctl(get) failed with error %d", GetLogPrefix(logPrefix), errno); + log.AddInfo(text); + } + else + { + flags = (b ? (flags&~O_NONBLOCK) : (flags|O_NONBLOCK)); + if(fcntl(socket,F_SETFL,flags) != -1) + { + return true; + } + else + { + char text[256]; + sprintf(text, "%s fnctl(set) failed with error %d", GetLogPrefix(logPrefix), errno); + log.AddInfo(text); + } + } + } + else + { + char text[256]; + sprintf(text, "%s setblocking(%s) failed, not initialized", GetLogPrefix(logPrefix), b?"true":"false"); + log.AddWarning(text); + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// + +EosTcpServer_Nix::EosTcpServer_Nix() + : m_Socket(-1) +{ +} + +//////////////////////////////////////////////////////////////////////////////// + +EosTcpServer_Nix::~EosTcpServer_Nix() +{ + Shutdown(); +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosTcpServer_Nix::Initialize(EosLog &log, unsigned short port) +{ + return Initialize(log, 0, port); +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosTcpServer_Nix::Initialize(EosLog &log, const char *ip, unsigned short port) +{ + if(m_Socket == -1) + { + const char *actualIP = (ip ? ip : "0.0.0.0"); + EosTcp::SetLogPrefix("tcp server", actualIP, port, m_LogPrefix); + + m_Socket = socket(AF_INET, SOCK_STREAM, 0); + if(m_Socket != -1) + { + int optval = 1; + if(setsockopt(m_Socket,SOL_SOCKET,SO_REUSEADDR,(const char*)&optval,sizeof(optval)) == -1) + { + char text[256]; + sprintf(text, "%s setsockopt(SO_REUSEADDR) failed with error %d", EosTcp::GetLogPrefix(m_LogPrefix), errno); + log.AddWarning(text); + } + + // ignore SIGPIPE + + signal(SIGPIPE, SIG_IGN); + + sockaddr_in addr; + std::memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(actualIP); + addr.sin_port = htons(port); + + int result = bind(m_Socket, reinterpret_cast(&addr), static_cast(sizeof(addr))); + if(result != -1) + { + result = listen(m_Socket, SOMAXCONN); + if(result != -1) + { + EosTcp_Nix::SetSocketBlocking(log, m_LogPrefix, m_Socket, false); + + char text[256]; + sprintf(text, "%s socket intialized", EosTcp::GetLogPrefix(m_LogPrefix)); + log.AddInfo(text); + + m_Listening = true; + } + else + { + char text[256]; + sprintf(text, "%s listen failed with error %d", EosTcp::GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + close(m_Socket); + m_Socket = -1; + } + } + else + { + char text[256]; + sprintf(text, "%s bind failed with error %d", EosTcp::GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + close(m_Socket); + m_Socket = -1; + } + } + else + { + char text[256]; + sprintf(text, "%s socket failed with error %d", EosTcp::GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s initialize failed, already initialized", EosTcp::GetLogPrefix(m_LogPrefix)); + log.AddWarning(text); + } + + return (m_Socket != -1); +} + +//////////////////////////////////////////////////////////////////////////////// + +void EosTcpServer_Nix::Shutdown() +{ + if(m_Socket != -1) + { + close(m_Socket); + m_Socket = -1; + } + + m_Listening = false; +} + +//////////////////////////////////////////////////////////////////////////////// + +EosTcp* EosTcpServer_Nix::Recv(EosLog &log, unsigned int timeoutMS, void *addr, int *addrSize) +{ + EosTcp *newConnection = 0; + + if(m_Socket != -1) + { + if( m_Listening ) + { + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(m_Socket, &readfds); + + timeval timeout; + timeout.tv_sec = timeoutMS/1000; + timeout.tv_usec = ((timeoutMS - timeoutMS/1000) * 1000); + + int result = select(m_Socket+1, &readfds, 0, 0, &timeout); + if(result > 0) + { + socklen_t addrLen = 0; + int s = accept(m_Socket, static_cast(addr), &addrLen); + if(s != -1) + { + *addrSize = static_cast(addrLen); + newConnection = EosTcp::Create(); + newConnection->InitializeAccepted(log, &s); + + sockaddr_in *addr_in = static_cast(addr); + char *ip = inet_ntoa( addr_in->sin_addr ); + char text[256]; + sprintf(text, "%s new connection(%s:%u)", EosTcp::GetLogPrefix(m_LogPrefix), ip ? ip : "", addr_in->sin_port); + log.AddInfo(text); + } + else + { + char text[256]; + sprintf(text, "%s accept failed with error %d", EosTcp::GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + } + } + else if(result < 0) + { + char text[256]; + sprintf(text, "%s select failed with error %d", EosTcp::GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + + m_Listening = false; + } + } + else + { + char text[256]; + sprintf(text, "%s recv failed, not listening", EosTcp::GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s recv failed, not initialized", EosTcp::GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + + return newConnection; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/EosSyncLib/EosTcp_Nix.h b/EosSyncLib/EosTcp_Nix.h new file mode 100644 index 0000000..7c35141 --- /dev/null +++ b/EosSyncLib/EosTcp_Nix.h @@ -0,0 +1,72 @@ +// Copyright (c) 2015 Electronic Theatre Controls, Inc., http://www.etcconnect.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once +#ifndef EOS_TCP_NIX_H +#define EOS_TCP_NIX_H + +#ifndef EOS_TCP_H +#include "EosTcp.h" +#endif + +//////////////////////////////////////////////////////////////////////////////// + +class EosTcp_Nix + : public EosTcp +{ +public: + EosTcp_Nix(); + virtual ~EosTcp_Nix(); + + virtual bool Initialize(EosLog &log, const char *ip, unsigned short port); + virtual bool InitializeAccepted(EosLog &log, void *pSocket); + virtual void Shutdown(); + virtual void Tick(EosLog &log); + virtual bool Send(EosLog &log, const char *data, size_t size); + virtual const char* Recv(EosLog &log, unsigned int timeoutMS, size_t &size); + + static bool SetSocketBlocking(EosLog &log, const std::string &logPrefix, int socket, bool b); + +private: + int m_Socket; + char *m_RecvBuf; +}; + +//////////////////////////////////////////////////////////////////////////////// + +class EosTcpServer_Nix + : public EosTcpServer +{ +public: + EosTcpServer_Nix(); + virtual ~EosTcpServer_Nix(); + + virtual bool Initialize(EosLog &log, unsigned short port); + virtual bool Initialize(EosLog &log, const char *ip, unsigned short port); + virtual void Shutdown(); + virtual EosTcp* Recv(EosLog &log, unsigned int timeoutMS, void *addr, int *addrSize); + +private: + int m_Socket; +}; + +//////////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/EosSyncLib/EosTimer.cpp b/EosSyncLib/EosTimer.cpp index eb7a4f8..9e7e2fd 100644 --- a/EosSyncLib/EosTimer.cpp +++ b/EosSyncLib/EosTimer.cpp @@ -23,11 +23,14 @@ #ifdef WIN32 #include #include -#else +#elif defined TARGET_OS_MAC #include #include #include double EosTimer::sm_toMS = 0; +#elif defined __linux__ + #include + #include #endif //////////////////////////////////////////////////////////////////////////////// @@ -71,7 +74,7 @@ bool EosTimer::GetExpired(unsigned int ms) const void EosTimer::Init() { -#ifndef WIN32 +#ifdef TARGET_OS_MAC if(sm_toMS == 0) { mach_timebase_info_data_t timeBase; @@ -88,8 +91,10 @@ unsigned int EosTimer::GetTimestamp() { #ifdef WIN32 return timeGetTime(); -#else +#elif defined TARGET_OS_MAC return static_cast(mach_absolute_time() * sm_toMS); +#elif defined __linux__ + return std::chrono::duration_cast (std::chrono::steady_clock::now().time_since_epoch()).count(); #endif } @@ -99,8 +104,10 @@ void EosTimer::SleepMS(unsigned int ms) { #ifdef WIN32 Sleep(ms); -#else +#elif defined TARGET_OS_MAC usleep(ms*1000); +#elif defined __linux__ + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); #endif } diff --git a/EosSyncLib/EosTimer.h b/EosSyncLib/EosTimer.h index 954486d..f30b170 100644 --- a/EosSyncLib/EosTimer.h +++ b/EosSyncLib/EosTimer.h @@ -42,7 +42,7 @@ class EosTimer private: unsigned int m_Timestamp; -#ifndef WIN32 +#ifdef TARGET_OS_MAC static double sm_toMS; #endif }; diff --git a/EosSyncLib/EosUdp.cpp b/EosSyncLib/EosUdp.cpp index b4cb056..7c78330 100644 --- a/EosSyncLib/EosUdp.cpp +++ b/EosSyncLib/EosUdp.cpp @@ -22,8 +22,10 @@ #ifdef WIN32 #include "EosUdp_Win.h" -#else +#elif defined TARGET_OS_MAC #include "EosUdp_Mac.h" +#elif defined __linux__ + #include "EosUdp_Nix.h" #endif //////////////////////////////////////////////////////////////////////////////// @@ -49,7 +51,7 @@ void EosUdpIn::SetLogPrefix(const char *name, const char *ip, unsigned short por else logPrefix.clear(); - size_t maxLen = strlen("255.255.255.255"); + size_t maxLen = std::string("255.255.255.255").length(); if(logPrefix.size() > maxLen) logPrefix.resize(maxLen); @@ -77,8 +79,10 @@ EosUdpIn* EosUdpIn::Create() { #ifdef WIN32 return (new EosUdpIn_Win()); -#else +#elif defined TARGET_OS_MAC return (new EosUdpIn_Mac()); +#elif defined __linux__ + return (new EosUdpIn_Nix()); #endif } @@ -88,8 +92,10 @@ EosUdpOut* EosUdpOut::Create() { #ifdef WIN32 return (new EosUdpOut_Win()); -#else +#elif defined TARGET_OS_MAC return (new EosUdpOut_Mac()); +#elif defined __linux__ + return (new EosUdpOut_Nix()); #endif } diff --git a/EosSyncLib/EosUdp_Mac.cpp b/EosSyncLib/EosUdp_Mac.cpp old mode 100755 new mode 100644 diff --git a/EosSyncLib/EosUdp_Nix.cpp b/EosSyncLib/EosUdp_Nix.cpp new file mode 100644 index 0000000..f64c29d --- /dev/null +++ b/EosSyncLib/EosUdp_Nix.cpp @@ -0,0 +1,291 @@ +// Copyright (c) 2015 Electronic Theatre Controls, Inc., http://www.etcconnect.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "EosUdp_Nix.h" +#include "EosLog.h" +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// + +EosUdpIn_Nix::EosUdpIn_Nix() + : m_Socket(-1) +{ +} + +//////////////////////////////////////////////////////////////////////////////// + +EosUdpIn_Nix::~EosUdpIn_Nix() +{ + Shutdown(); +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosUdpIn_Nix::Initialize(EosLog &log, const char *ip, unsigned short port) +{ + if( !IsInitialized() ) + { + SetLogPrefix("udp input", ip, port, m_LogPrefix); + + if( ip ) + { + m_Socket = socket(AF_INET, SOCK_DGRAM, 0); + if(m_Socket != -1) + { + int optval = 1; + if(setsockopt(m_Socket,SOL_SOCKET,SO_REUSEADDR,(const char*)&optval,sizeof(optval)) == -1) + { + char text[256]; + sprintf(text, "%s setsockopt(SO_REUSEADDR) failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddWarning(text); + } + + sockaddr_in addr; + std::memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(ip); + addr.sin_port = htons(port); + int result = bind(m_Socket, reinterpret_cast(&addr), static_cast(sizeof(addr))); + if(result != -1) + { + char text[256]; + sprintf(text, "%s socket intialized", GetLogPrefix(m_LogPrefix)); + log.AddInfo(text); + } + else + { + char text[256]; + sprintf(text, "%s bind failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + close(m_Socket); + m_Socket = -1; + } + } + else + { + char text[256]; + sprintf(text, "%s socket failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s initialize failed, invalid arguments", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s initialize failed, already initialized", GetLogPrefix(m_LogPrefix)); + log.AddWarning(text); + } + + return IsInitialized(); +} + +//////////////////////////////////////////////////////////////////////////////// + +void EosUdpIn_Nix::Shutdown() +{ + if( IsInitialized() ) + { + close(m_Socket); + m_Socket = -1; + } +} + +//////////////////////////////////////////////////////////////////////////////// + +const char* EosUdpIn_Nix::RecvPacket(EosLog &log, unsigned int timeoutMS, unsigned int retryCount, int &len, void *addr, int *addrSize) +{ + if( IsInitialized() ) + { + for(;;) + { + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(m_Socket, &readfds); + + timeval timeout; + timeout.tv_sec = timeoutMS/1000; + timeout.tv_usec = ((timeoutMS - timeoutMS/1000) * 1000); + + int result = select(m_Socket+1, &readfds, 0, 0, &timeout); + if(result > 0) + { + socklen_t fromSize = (addrSize ? static_cast(*addrSize) : 0); + len = static_cast( recvfrom(m_Socket,m_RecvBuf,EOS_UDP_RECV_BUF_LEN,0,static_cast(addr),(addr && addrSize) ? (&fromSize) : 0) ); + if(len == -1) + { + char text[256]; + sprintf(text, "%s recvfrom failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + } + else if(len < 1) + { + char text[256]; + sprintf(text, "%s recvfrom failed, received %d bytes", GetLogPrefix(m_LogPrefix), len); + log.AddWarning(text); + } + else + return m_RecvBuf; + } + else if(result < 0) + { + char text[256]; + sprintf(text, "%s select failed with error %d", GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + break; + } + + if(retryCount-- == 0) + break; + } + } + else + { + char text[256]; + sprintf(text, "%s RecvPacket failed, not initialized", GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + + return 0; +} + +//////////////////////////////////////////////////////////////////////////////// + +EosUdpOut_Nix::EosUdpOut_Nix() + : m_Socket(-1) +{ +} + +//////////////////////////////////////////////////////////////////////////////// + +EosUdpOut_Nix::~EosUdpOut_Nix() +{ + Shutdown(); +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosUdpOut_Nix::Initialize(EosLog &log, const char *ip, unsigned short port) +{ + if( !IsInitialized() ) + { + EosUdpIn::SetLogPrefix("udp output", ip, port, m_LogPrefix); + + if( ip ) + { + m_Socket = socket(AF_INET, SOCK_DGRAM, 0); + if(m_Socket != -1) + { + int optval = 1; + if(setsockopt(m_Socket,SOL_SOCKET,SO_BROADCAST,(const char*)&optval,sizeof(optval)) == -1) + { + char text[256]; + sprintf(text, "%s setsockopt(SO_BROADCAST) failed with error %d", EosUdpIn::GetLogPrefix(m_LogPrefix), errno); + log.AddWarning(text); + } + + std::memset(&m_Addr, 0, sizeof(m_Addr)); + m_Addr.sin_family = AF_INET; + m_Addr.sin_addr.s_addr = inet_addr(ip); + m_Addr.sin_port = htons(port); + + char text[256]; + sprintf(text, "%s socket intialized", EosUdpIn::GetLogPrefix(m_LogPrefix)); + log.AddInfo(text); + } + else + { + char text[256]; + sprintf(text, "%s socket failed with error %d", EosUdpIn::GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s initialize failed, invalid arguments", EosUdpIn::GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + } + else + { + char text[256]; + sprintf(text, "%s initialize failed, already initialized", EosUdpIn::GetLogPrefix(m_LogPrefix)); + log.AddWarning(text); + } + + return IsInitialized(); +} + +//////////////////////////////////////////////////////////////////////////////// + +void EosUdpOut_Nix::Shutdown() +{ + if( IsInitialized() ) + { + close(m_Socket); + m_Socket = -1; + } +} + +//////////////////////////////////////////////////////////////////////////////// + +bool EosUdpOut_Nix::SendPacket(EosLog &log, const char *buf, int len) +{ + if( IsInitialized() ) + { + if(buf && len>0) + { + int bytesSent = static_cast( sendto(m_Socket,buf,len,0,reinterpret_cast(&m_Addr),static_cast(sizeof(m_Addr))) ); + if(bytesSent == -1) + { + char text[256]; + sprintf(text, "%s sendto failed with error %d", EosUdpIn::GetLogPrefix(m_LogPrefix), errno); + log.AddError(text); + } + else if(bytesSent != len) + { + char text[256]; + sprintf(text, "%s sendto failed, sent %d of %d bytes", EosUdpIn::GetLogPrefix(m_LogPrefix), bytesSent, len); + log.AddError(text); + } + else + return true; + } + } + else + { + char text[256]; + sprintf(text, "%s SendPacket failed, not initialized", EosUdpIn::GetLogPrefix(m_LogPrefix)); + log.AddError(text); + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/EosSyncLib/EosUdp_Nix.h b/EosSyncLib/EosUdp_Nix.h new file mode 100644 index 0000000..5333001 --- /dev/null +++ b/EosSyncLib/EosUdp_Nix.h @@ -0,0 +1,72 @@ +// Copyright (c) 2015 Electronic Theatre Controls, Inc., http://www.etcconnect.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once +#ifndef EOS_UDP_NIX_H +#define EOS_UDP_NIX_H + +#ifndef EOS_UDP_H +#include "EosUdp.h" +#endif + +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////// + +class EosUdpIn_Nix + : public EosUdpIn +{ +public: + EosUdpIn_Nix(); + virtual ~EosUdpIn_Nix(); + + virtual bool Initialize(EosLog &log, const char *ip, unsigned short port); + virtual bool IsInitialized() const {return (m_Socket!=-1);} + virtual void Shutdown(); + virtual const char* RecvPacket(EosLog &log, unsigned int timeoutMS, unsigned int retryCount, int &len, void *addr, int *addrSize); + +private: + int m_Socket; +}; + +//////////////////////////////////////////////////////////////////////////////// + +class EosUdpOut_Nix + : public EosUdpOut +{ +public: + EosUdpOut_Nix(); + virtual ~EosUdpOut_Nix(); + + virtual bool Initialize(EosLog &log, const char *ip, unsigned short port); + virtual bool IsInitialized() const {return (m_Socket!=-1);} + virtual void Shutdown(); + virtual bool SendPacket(EosLog &log, const char *buf, int len); + +private: + int m_Socket; + sockaddr_in m_Addr; +}; + +//////////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/EosSyncLib/Makefile b/EosSyncLib/Makefile new file mode 100644 index 0000000..9e558e1 --- /dev/null +++ b/EosSyncLib/Makefile @@ -0,0 +1,284 @@ +############################################################################# +# Makefile for building: ../../bin/EosSyncTest +# Generated by qmake (2.01a) (Qt 4.8.7) on: Fri May 26 11:43:23 2017 +# Project: EosSyncLib.pro +# Template: app +# Command: /usr/bin/qmake-qt4 -o Makefile EosSyncLib.pro +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +DEFINES = -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED +CFLAGS = -pipe -g -Wall -W -D_REENTRANT $(DEFINES) +CXXFLAGS = -pipe -g -Wall -W -D_REENTRANT $(DEFINES) +INCPATH = -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. +LINK = g++ +LFLAGS = -Wl,-O1,--sort-common,--as-needed,-z,relro +LIBS = $(SUBLIBS) -L/usr/lib -lQtGui -lQtCore -lpthread +AR = ar cqs +RANLIB = +QMAKE = /usr/bin/qmake-qt4 +TAR = tar -cf +COMPRESS = gzip -9f +COPY = cp -f +SED = sed +COPY_FILE = $(COPY) +COPY_DIR = $(COPY) -r +STRIP = strip +INSTALL_FILE = install -m 644 -p +INSTALL_DIR = $(COPY_DIR) +INSTALL_PROGRAM = install -m 755 -p +DEL_FILE = rm -f +SYMLINK = ln -f -s +DEL_DIR = rmdir +MOVE = mv -f +CHK_DIR_EXISTS= test -d +MKDIR = mkdir -p + +####### Output directory + +OBJECTS_DIR = ./ + +####### Files + +SOURCES = EosLog.cpp \ + EosOsc.cpp \ + EosSyncLib.cpp \ + EosTcp.cpp \ + EosTimer.cpp \ + EosUdp.cpp \ + main.cpp \ + OSCParser.cpp \ + EosTcp_Nix.cpp \ + EosUdp_Nix.cpp +OBJECTS = EosLog.o \ + EosOsc.o \ + EosSyncLib.o \ + EosTcp.o \ + EosTimer.o \ + EosUdp.o \ + main.o \ + OSCParser.o \ + EosTcp_Nix.o \ + EosUdp_Nix.o +DIST = /usr/share/qt4/mkspecs/common/unix.conf \ + /usr/share/qt4/mkspecs/common/linux.conf \ + /usr/share/qt4/mkspecs/common/gcc-base.conf \ + /usr/share/qt4/mkspecs/common/gcc-base-unix.conf \ + /usr/share/qt4/mkspecs/common/g++-base.conf \ + /usr/share/qt4/mkspecs/common/g++-unix.conf \ + /usr/share/qt4/mkspecs/qconfig.pri \ + /usr/share/qt4/mkspecs/features/qt_functions.prf \ + /usr/share/qt4/mkspecs/features/qt_config.prf \ + /usr/share/qt4/mkspecs/features/exclusive_builds.prf \ + /usr/share/qt4/mkspecs/features/default_pre.prf \ + /usr/share/qt4/mkspecs/features/debug.prf \ + /usr/share/qt4/mkspecs/features/default_post.prf \ + /usr/share/qt4/mkspecs/features/shared.prf \ + /usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf \ + /usr/share/qt4/mkspecs/features/warn_on.prf \ + /usr/share/qt4/mkspecs/features/qt.prf \ + /usr/share/qt4/mkspecs/features/unix/thread.prf \ + /usr/share/qt4/mkspecs/features/moc.prf \ + /usr/share/qt4/mkspecs/features/resources.prf \ + /usr/share/qt4/mkspecs/features/uic.prf \ + /usr/share/qt4/mkspecs/features/yacc.prf \ + /usr/share/qt4/mkspecs/features/lex.prf \ + /usr/share/qt4/mkspecs/features/include_source_dir.prf \ + EosSyncLib.pro +QMAKE_TARGET = EosSyncTest +DESTDIR = ../../bin/ +TARGET = ../../bin/EosSyncTest + +first: all +####### Implicit rules + +.SUFFIXES: .o .c .cpp .cc .cxx .C + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<" + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<" + +####### Build rules + +all: Makefile $(TARGET) + +$(TARGET): $(OBJECTS) + @$(CHK_DIR_EXISTS) ../../bin/ || $(MKDIR) ../../bin/ + $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS) + { test -n "$(DESTDIR)" && DESTDIR="$(DESTDIR)" || DESTDIR=.; } && test $$(gdb --version | sed -e 's,[^0-9][^0-9]*\([0-9]\)\.\([0-9]\).*,\1\2,;q') -gt 72 && gdb --nx --batch --quiet -ex 'set confirm off' -ex "save gdb-index $$DESTDIR" -ex quit '$(TARGET)' && test -f $(TARGET).gdb-index && objcopy --add-section '.gdb_index=$(TARGET).gdb-index' --set-section-flags '.gdb_index=readonly' '$(TARGET)' '$(TARGET)' && rm -f $(TARGET).gdb-index || true + +Makefile: EosSyncLib.pro /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mkspecs/common/unix.conf \ + /usr/share/qt4/mkspecs/common/linux.conf \ + /usr/share/qt4/mkspecs/common/gcc-base.conf \ + /usr/share/qt4/mkspecs/common/gcc-base-unix.conf \ + /usr/share/qt4/mkspecs/common/g++-base.conf \ + /usr/share/qt4/mkspecs/common/g++-unix.conf \ + /usr/share/qt4/mkspecs/qconfig.pri \ + /usr/share/qt4/mkspecs/features/qt_functions.prf \ + /usr/share/qt4/mkspecs/features/qt_config.prf \ + /usr/share/qt4/mkspecs/features/exclusive_builds.prf \ + /usr/share/qt4/mkspecs/features/default_pre.prf \ + /usr/share/qt4/mkspecs/features/debug.prf \ + /usr/share/qt4/mkspecs/features/default_post.prf \ + /usr/share/qt4/mkspecs/features/shared.prf \ + /usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf \ + /usr/share/qt4/mkspecs/features/warn_on.prf \ + /usr/share/qt4/mkspecs/features/qt.prf \ + /usr/share/qt4/mkspecs/features/unix/thread.prf \ + /usr/share/qt4/mkspecs/features/moc.prf \ + /usr/share/qt4/mkspecs/features/resources.prf \ + /usr/share/qt4/mkspecs/features/uic.prf \ + /usr/share/qt4/mkspecs/features/yacc.prf \ + /usr/share/qt4/mkspecs/features/lex.prf \ + /usr/share/qt4/mkspecs/features/include_source_dir.prf \ + /usr/lib/libQtGui.prl \ + /usr/lib/libQtCore.prl + $(QMAKE) -o Makefile EosSyncLib.pro +/usr/share/qt4/mkspecs/common/unix.conf: +/usr/share/qt4/mkspecs/common/linux.conf: +/usr/share/qt4/mkspecs/common/gcc-base.conf: +/usr/share/qt4/mkspecs/common/gcc-base-unix.conf: +/usr/share/qt4/mkspecs/common/g++-base.conf: +/usr/share/qt4/mkspecs/common/g++-unix.conf: +/usr/share/qt4/mkspecs/qconfig.pri: +/usr/share/qt4/mkspecs/features/qt_functions.prf: +/usr/share/qt4/mkspecs/features/qt_config.prf: +/usr/share/qt4/mkspecs/features/exclusive_builds.prf: +/usr/share/qt4/mkspecs/features/default_pre.prf: +/usr/share/qt4/mkspecs/features/debug.prf: +/usr/share/qt4/mkspecs/features/default_post.prf: +/usr/share/qt4/mkspecs/features/shared.prf: +/usr/share/qt4/mkspecs/features/unix/gdb_dwarf_index.prf: +/usr/share/qt4/mkspecs/features/warn_on.prf: +/usr/share/qt4/mkspecs/features/qt.prf: +/usr/share/qt4/mkspecs/features/unix/thread.prf: +/usr/share/qt4/mkspecs/features/moc.prf: +/usr/share/qt4/mkspecs/features/resources.prf: +/usr/share/qt4/mkspecs/features/uic.prf: +/usr/share/qt4/mkspecs/features/yacc.prf: +/usr/share/qt4/mkspecs/features/lex.prf: +/usr/share/qt4/mkspecs/features/include_source_dir.prf: +/usr/lib/libQtGui.prl: +/usr/lib/libQtCore.prl: +qmake: FORCE + @$(QMAKE) -o Makefile EosSyncLib.pro + +dist: + @$(CHK_DIR_EXISTS) .tmp/EosSyncTest1.0.0 || $(MKDIR) .tmp/EosSyncTest1.0.0 + $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/EosSyncTest1.0.0/ && $(COPY_FILE) --parents EosLog.h EosOsc.h EosSyncLib.h EosTcp.h EosTimer.h EosUdp.h OSCParser.h EosTcp_Nix.h EosUdp_Nix.h .tmp/EosSyncTest1.0.0/ && $(COPY_FILE) --parents EosLog.cpp EosOsc.cpp EosSyncLib.cpp EosTcp.cpp EosTimer.cpp EosUdp.cpp main.cpp OSCParser.cpp EosTcp_Nix.cpp EosUdp_Nix.cpp .tmp/EosSyncTest1.0.0/ && (cd `dirname .tmp/EosSyncTest1.0.0` && $(TAR) EosSyncTest1.0.0.tar EosSyncTest1.0.0 && $(COMPRESS) EosSyncTest1.0.0.tar) && $(MOVE) `dirname .tmp/EosSyncTest1.0.0`/EosSyncTest1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/EosSyncTest1.0.0 + + +clean:compiler_clean + -$(DEL_FILE) $(OBJECTS) + -$(DEL_FILE) *~ core *.core + + +####### Sub-libraries + +distclean: clean + -$(DEL_FILE) $(TARGET) + -$(DEL_FILE) Makefile + + +check: first + +mocclean: compiler_moc_header_clean compiler_moc_source_clean + +mocables: compiler_moc_header_make_all compiler_moc_source_make_all + +compiler_moc_header_make_all: +compiler_moc_header_clean: +compiler_rcc_make_all: +compiler_rcc_clean: +compiler_image_collection_make_all: qmake_image_collection.cpp +compiler_image_collection_clean: + -$(DEL_FILE) qmake_image_collection.cpp +compiler_moc_source_make_all: +compiler_moc_source_clean: +compiler_uic_make_all: +compiler_uic_clean: +compiler_yacc_decl_make_all: +compiler_yacc_decl_clean: +compiler_yacc_impl_make_all: +compiler_yacc_impl_clean: +compiler_lex_make_all: +compiler_lex_clean: +compiler_clean: + +####### Compile + +EosLog.o: EosLog.cpp EosLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EosLog.o EosLog.cpp + +EosOsc.o: EosOsc.cpp EosOsc.h \ + OSCParser.h \ + EosTcp.h \ + EosLog.h \ + EosTimer.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EosOsc.o EosOsc.cpp + +EosSyncLib.o: EosSyncLib.cpp EosSyncLib.h \ + EosLog.h \ + EosOsc.h \ + OSCParser.h \ + EosTcp.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EosSyncLib.o EosSyncLib.cpp + +EosTcp.o: EosTcp.cpp EosTcp.h \ + EosLog.h \ + EosTcp_Win.h \ + EosTcp_Mac.h \ + EosTcp_Nix.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EosTcp.o EosTcp.cpp + +EosTimer.o: EosTimer.cpp EosTimer.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EosTimer.o EosTimer.cpp + +EosUdp.o: EosUdp.cpp EosUdp.h \ + EosUdp_Win.h \ + EosUdp_Mac.h \ + EosUdp_Nix.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EosUdp.o EosUdp.cpp + +main.o: main.cpp EosSyncLib.h \ + EosLog.h \ + EosOsc.h \ + OSCParser.h \ + EosTimer.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp + +OSCParser.o: OSCParser.cpp OSCParser.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o OSCParser.o OSCParser.cpp + +EosTcp_Nix.o: EosTcp_Nix.cpp EosTcp_Nix.h \ + EosTcp.h \ + EosLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EosTcp_Nix.o EosTcp_Nix.cpp + +EosUdp_Nix.o: EosUdp_Nix.cpp EosUdp_Nix.h \ + EosUdp.h \ + EosLog.h + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o EosUdp_Nix.o EosUdp_Nix.cpp + +####### Install + +install: FORCE + +uninstall: FORCE + +FORCE: + diff --git a/EosSyncLib/OSCParser.cpp b/EosSyncLib/OSCParser.cpp old mode 100755 new mode 100644 diff --git a/EosSyncLib/main.cpp b/EosSyncLib/main.cpp index 9aa7e48..125aa61 100644 --- a/EosSyncLib/main.cpp +++ b/EosSyncLib/main.cpp @@ -21,6 +21,7 @@ #include "EosSyncLib.h" #include "EosTimer.h" #include +#include //////////////////////////////////////////////////////////////////////////////// @@ -38,8 +39,8 @@ void FlushLogQ(EosSyncLib &eosSyncLib) const char *type = 0; switch( msg.type ) { - //case EosLog::LOG_MSG_TYPE_DEBUG: type="Debug"; break; - //case EosLog::LOG_MSG_TYPE_INFO: type="Info"; break; + case EosLog::LOG_MSG_TYPE_DEBUG: type="Debug"; break; + case EosLog::LOG_MSG_TYPE_INFO: type="Info"; break; case EosLog::LOG_MSG_TYPE_WARNING: type="Warning"; break; case EosLog::LOG_MSG_TYPE_ERROR: type="Error"; break; } @@ -76,14 +77,17 @@ void PrintSummary(const EosSyncData &syncData) //////////////////////////////////////////////////////////////////////////////// -int main(int /*argc*/, char** /*argv*/) +int main(int argc, char **argv) { + char *ip = "127.0.0.1"; + unsigned short port = EosSyncLib::DEFAULT_PORT; + EosTimer::Init(); printf("Connecting...\n"); EosSyncLib eosSyncLib; - if( eosSyncLib.Initialize("127.0.0.1",EosSyncLib::DEFAULT_PORT) ) + if( eosSyncLib.Initialize(ip, port) ) { bool wasConnected = false; bool wasSyncd = false; diff --git a/README.md b/README.md index d8e670a..2bc7699 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,15 @@ A C++ library (with no 3rd party dependencies) for accessing Eos show data in re [EosFamily_ShowControl_UserGuide_RevB](http://www.etcconnect.com/WorkArea/DownloadAsset.aspx?id=10737461372) -##About this ETCLabs Project +## About this ETCLabs Project EosSyncLib is open-source software (developed by a combination of end users and ETC employees in their free time) designed to interact with Electronic Theatre Controls products. This is not official ETC software. For challenges using, integrating, compiling, or modifying this software, we encourage posting on the [Issues](https://github.com/ElectronicTheatreControlsLabs/EosSyncLib/issues) page of this project. ETC Support is not familiar with this software and will not be able to assist if issues arise. (Hopefully issues won't happen, and you'll have a lot of fun with these tools and toys!) We also welcome pull requests for bug fixes and feature additions. -#Simple Example +## This Fork +The purpose of this fork is to add Linux compatibility with as little change as possible to the overall codebase, and without breaking compatibility with other platforms. + +# Simple Example ```C++ #include "EosSyncLib.h" #include "EosTimer.h"