#include "olathread.h" #include olaThread::olaThread(QObject *parent) { Q_UNUSED(parent); m_counter = 0; gettimeofday(&m_last_data, NULL); // Init the dmx buffer to 0 for (int i=0; i < LAYERS_NUMBER; i++) { for (int j=0; j < LAYER_CHANNELS; j++) { m_dmx[i][j] = 0; } } init(); // start the ola connection } // --- DECONSTRUCTOR --- olaThread::~olaThread() { stop(); } void olaThread::init() { if (ola::InitLogging(ola::OLA_LOG_INFO , ola::OLA_LOG_STDERR)) { qDebug() << "ola logging debug working"; } else { qWarning() << "Can not init ola logging"; } m_clientWrapper = new ola::client::OlaClientWrapper; Q_CHECK_PTR(m_clientWrapper); if (!m_clientWrapper->Setup()) { qErrnoWarning("olaThread::olaStart| Failed Setup() in Client Wrapper"); } m_client = m_clientWrapper->GetClient(); m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::NewDmx)); m_clientWrapper->GetSelectServer()->RegisterRepeatingTimeout(4000, ola::NewCallback(this, &olaThread::CheckDataLoss)); m_client->SetCloseHandler(ola::NewSingleCallback(this, &olaThread::socketClosed)); } void olaThread::run() { emit toTerminal("Start reading DMX"); m_clientWrapper->GetSelectServer()->Run(); } void olaThread::stop() { if (m_clientWrapper != NULL) { QSet temp = Settings::getInstance()->getUniverses(); foreach (const int &i, temp) { m_client->RegisterUniverse(i, ola::client::UNREGISTER, ola::NewSingleCallback(this, &olaThread::RegisterComplete)); } m_clientWrapper->GetSelectServer()->Terminate(); m_clientWrapper = NULL; m_client = NULL; } } // ToDo: It can be more efficient making the dmx buffer a DmxBuffer class instead a int array and compare with the new if there is changes at start. Also all access to the buffer it should be get/set. I should profile this void olaThread::NewDmx(const ola::client::DMXMetadata &data, const ola::DmxBuffer &buffer) { m_counter++; gettimeofday(&m_last_data, NULL); uint universe = data.universe; emit layerReceived(); foreach (const dmxSetting &i, Settings::getInstance()->getDmxSettings()) { // loop for reading the channels by layer. if(i.universe == universe && i.address > -1) { // Compare if the layer is from this universe AND if the DMX address is 0 or greater, process this layer. for (int j = 0; j < LAYER_CHANNELS; j++){ int value = buffer.Get((i.address) + j); // Get the value for this channel. if (m_dmx[i.layer][j] != value) { // Compare the new value with the old value. emit dmxOutput(i.layer,j,value); m_dmx[i.layer][j] = value; } } } } } /** * Check for data loss each 4 seconds. */ bool olaThread::CheckDataLoss() { struct timeval now, diff; if (timerisset(&m_last_data)) { gettimeofday(&now, NULL); timersub(&now, &m_last_data, &diff); if (diff.tv_sec > 4 || (diff.tv_sec == 4 && diff.tv_usec > 4000000)) { // loss of data qDebug()<< "olaThread| Can not read one or several universes"; emit toTerminal("olaThread: Can not read one universe"); // return false; // Retorna false para deshabilitar el callback } } return true; } void olaThread::resendDmx() { // qDebug() << "Resending DMX info"; for (int i = 0; i < Settings::getInstance()->getLayersNumber(); i++) { // loop for reading the channels by layer. for (int j = 0; j < LAYER_CHANNELS; j++){ emit dmxOutput(i, j, m_dmx[i][j]); // Connected with dmx slot in olaInterface. } } } void olaThread::socketClosed() { qWarning("ola close the connection. Trying reopening it... "); emit toTerminal("OLA closed the connection. Tryin reopening it... "); // Qúe limpiamos? todo? el thread? if (!m_client->Stop()) { qWarning("Can not stop the ola client"); } m_clientWrapper->GetSelectServer()->Terminate(); delete m_client; m_client = NULL; delete m_clientWrapper; m_clientWrapper = NULL; // set up ola connection init(); // register all universes registerUniverse(); // start the thread???? run(); } ////////////////////////////////////////////////////////////////////////////////////////////