/* * Check that we update when ports have new data */ void UniverseTest::testReceiveDmx() { ola::PortBroker broker; ola::PortManager port_manager(m_store, &broker); TimeStamp time_stamp; MockSelectServer ss(&time_stamp); ola::PluginAdaptor plugin_adaptor(NULL, &ss, NULL, NULL, NULL, NULL); MockDevice device(NULL, "foo"); TestMockInputPort port(&device, 1, &plugin_adaptor); // input port port_manager.PatchPort(&port, TEST_UNIVERSE); Universe *universe = m_store->GetUniverseOrCreate(TEST_UNIVERSE); OLA_ASSERT(universe); OLA_ASSERT_EQ((unsigned int) 1, universe->InputPortCount()); OLA_ASSERT_EQ((unsigned int) 0, universe->OutputPortCount()); OLA_ASSERT(universe->IsActive()); // Setup the port with some data, and check that signalling the universe // works. m_clock.CurrentTime(&time_stamp); port.WriteDMX(m_buffer); port.DmxChanged(); OLA_ASSERT_EQ(ola::dmx::SOURCE_PRIORITY_DEFAULT, universe->ActivePriority()); OLA_ASSERT_EQ(m_buffer.Size(), universe->GetDMX().Size()); OLA_ASSERT(m_buffer == universe->GetDMX()); // Remove the port from the universe universe->RemovePort(&port); OLA_ASSERT_FALSE(universe->IsActive()); OLA_ASSERT_EQ((unsigned int) 0, universe->InputPortCount()); OLA_ASSERT_EQ((unsigned int) 0, universe->OutputPortCount()); }
bool PortManager::GenericUnPatchPort(PortClass *port) { if (!port) return false; Universe *universe = port->GetUniverse(); m_broker->RemovePort(port); if (universe) { universe->RemovePort(port); port->SetUniverse(NULL); OLA_INFO << "Unpatched " << port->UniqueId() << " from uni " << universe->UniverseId(); } return true; }
bool PortManager::GenericPatchPort(PortClass *port, unsigned int new_universe_id) { if (!port) return false; Universe *universe = port->GetUniverse(); if (universe && universe->UniverseId() == new_universe_id) return true; AbstractDevice *device = port->GetDevice(); if (device) { if (!device->AllowLooping()) { // check ports of the opposite type if (CheckLooping<PortClass>(device, new_universe_id)) return false; } if (!device->AllowMultiPortPatching()) { if (CheckMultiPort<PortClass>(device, new_universe_id)) return false; } } // unpatch if required if (universe) { OLA_DEBUG << "Port " << port->UniqueId() << " is bound to universe " << universe->UniverseId(); m_broker->RemovePort(port); universe->RemovePort(port); } universe = m_universe_store->GetUniverseOrCreate(new_universe_id); if (!universe) return false; if (port->SetUniverse(universe)) { OLA_INFO << "Patched " << port->UniqueId() << " to universe " << universe->UniverseId(); m_broker->AddPort(port); universe->AddPort(port); } else { if (!universe->IsActive()) m_universe_store->AddUniverseGarbageCollection(universe); } return true; }
/* * Check that SendDmx updates all ports */ void UniverseTest::testSendDmx() { Universe *universe = m_store->GetUniverseOrCreate(TEST_UNIVERSE); OLA_ASSERT(universe); TestMockOutputPort port(NULL, 1); // output port universe->AddPort(&port); OLA_ASSERT_EQ((unsigned int) 0, universe->InputPortCount()); OLA_ASSERT_EQ((unsigned int) 1, universe->OutputPortCount()); OLA_ASSERT(universe->IsActive()); // send some data to the universe and check the port gets it OLA_ASSERT(universe->SetDMX(m_buffer)); OLA_ASSERT(m_buffer == port.ReadDMX()); // remove the port from the universe universe->RemovePort(&port); OLA_ASSERT_EQ((unsigned int) 0, universe->InputPortCount()); OLA_ASSERT_EQ((unsigned int) 0, universe->OutputPortCount()); OLA_ASSERT_FALSE(universe->IsActive()); }
void Device::GenericDeletePort(PortClass *port) { Universe *universe = port->GetUniverse(); if (universe) universe->RemovePort(port); delete port; }
/** * test Sending an RDM request */ void UniverseTest::testRDMSend() { Universe *universe = m_store->GetUniverseOrCreate(TEST_UNIVERSE); OLA_ASSERT(universe); // setup the ports with a UID on each UID uid1(0x7a70, 1); UID uid2(0x7a70, 2); UID uid3(0x7a70, 3); UIDSet port1_uids, port2_uids; port1_uids.AddUID(uid1); port2_uids.AddUID(uid2); TestMockRDMOutputPort port1(NULL, 1, &port1_uids, true); TestMockRDMOutputPort port2(NULL, 2, &port2_uids, true); universe->AddPort(&port1); port1.SetUniverse(universe); universe->AddPort(&port2); port2.SetUniverse(universe); UID source_uid(0x7a70, 100); // first try a command to a uid we don't know about const RDMRequest *request = new ola::rdm::RDMGetRequest( source_uid, uid3, 0, // transaction # 1, // port id 0, // message count 10, // sub device 296, // param id NULL, 0); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_UNKNOWN_UID, reinterpret_cast<const RDMResponse*>(NULL))); // ok, now try something that returns a response from the port request = new ola::rdm::RDMGetRequest( source_uid, uid1, 0, // transaction # 1, // port id 0, // message count 10, // sub device 296, // param id NULL, 0); port1.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_TIMEOUT)); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_TIMEOUT, reinterpret_cast<const RDMResponse*>(NULL))); // now try a broadcast fan out UID vendorcast_uid = UID::VendorcastAddress(0x7a70); request = new ola::rdm::RDMGetRequest( source_uid, vendorcast_uid, 0, // transaction # 1, // port id 0, // message count 10, // sub device 296, // param id NULL, 0); port1.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_WAS_BROADCAST)); port2.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_WAS_BROADCAST)); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_WAS_BROADCAST, reinterpret_cast<const RDMResponse*>(NULL))); // now confirm that if one of the ports fails to send, we see this response request = new ola::rdm::RDMGetRequest( source_uid, vendorcast_uid, 0, // transaction # 1, // port id 0, // message count 10, // sub device 296, // param id NULL, 0); port2.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_FAILED_TO_SEND)); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_FAILED_TO_SEND, reinterpret_cast<const RDMResponse*>(NULL))); // DUB responses are slightly different request = NewDiscoveryUniqueBranchRequest(source_uid, uid1, uid2, 0); port1.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_DUB_RESPONSE)); port2.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_DUB_RESPONSE)); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_DUB_RESPONSE, reinterpret_cast<const RDMResponse*>(NULL))); // now check that we still get a RDM_DUB_RESPONSE even if one port returns an // RDM_TIMEOUT request = NewDiscoveryUniqueBranchRequest(source_uid, uid1, uid2, 0); port2.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_TIMEOUT)); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_DUB_RESPONSE, reinterpret_cast<const RDMResponse*>(NULL))); // and the same again but the second port returns // RDM_PLUGIN_DISCOVERY_NOT_SUPPORTED request = NewDiscoveryUniqueBranchRequest(source_uid, uid1, uid2, 0); port2.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_PLUGIN_DISCOVERY_NOT_SUPPORTED)); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_DUB_RESPONSE, reinterpret_cast<const RDMResponse*>(NULL))); // now the first port returns a RDM_TIMEOUT request = NewDiscoveryUniqueBranchRequest(source_uid, uid1, uid2, 0); port1.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_TIMEOUT)); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_TIMEOUT, reinterpret_cast<const RDMResponse*>(NULL))); // finally if neither ports support the DUB, we should return that request = NewDiscoveryUniqueBranchRequest(source_uid, uid1, uid2, 0); port1.SetRDMHandler( NewCallback(this, &UniverseTest::ReturnRDMCode, ola::rdm::RDM_PLUGIN_DISCOVERY_NOT_SUPPORTED)); universe->SendRDMRequest( request, NewSingleCallback(this, &UniverseTest::ConfirmRDM, __LINE__, ola::rdm::RDM_PLUGIN_DISCOVERY_NOT_SUPPORTED, reinterpret_cast<const RDMResponse*>(NULL))); universe->RemovePort(&port1); universe->RemovePort(&port2); }
/** * Test RDM discovery for a universe/ */ void UniverseTest::testRDMDiscovery() { Universe *universe = m_store->GetUniverseOrCreate(TEST_UNIVERSE); OLA_ASSERT(universe); // check the uid set is initially empty UIDSet universe_uids; universe->GetUIDs(&universe_uids); OLA_ASSERT_EQ(0u, universe_uids.Size()); UID uid1(0x7a70, 1); UID uid2(0x7a70, 2); UID uid3(0x7a70, 3); UIDSet port1_uids, port2_uids; port1_uids.AddUID(uid1); port2_uids.AddUID(uid2); TestMockRDMOutputPort port1(NULL, 1, &port1_uids); // this port is configured to update the uids on patch TestMockRDMOutputPort port2(NULL, 2, &port2_uids, true); universe->AddPort(&port1); port1.SetUniverse(universe); universe->AddPort(&port2); port2.SetUniverse(universe); OLA_ASSERT_EQ((unsigned int) 0, universe->InputPortCount()); OLA_ASSERT_EQ((unsigned int) 2, universe->OutputPortCount()); universe->GetUIDs(&universe_uids); OLA_ASSERT_EQ(1u, universe_uids.Size()); OLA_ASSERT(universe_uids.Contains(uid2)); OLA_ASSERT(universe->IsActive()); // now trigger discovery UIDSet expected_uids; expected_uids.AddUID(uid1); expected_uids.AddUID(uid2); universe->RunRDMDiscovery( NewSingleCallback(this, &UniverseTest::ConfirmUIDs, &expected_uids), true); // now add a uid to one port, and remove a uid from another port1_uids.AddUID(uid3); port2_uids.RemoveUID(uid2); expected_uids.AddUID(uid3); expected_uids.RemoveUID(uid2); universe->RunRDMDiscovery( NewSingleCallback(this, &UniverseTest::ConfirmUIDs, &expected_uids), true); // remove the first port from the universe and confirm there are no more UIDs universe->RemovePort(&port1); expected_uids.Clear(); universe->RunRDMDiscovery( NewSingleCallback(this, &UniverseTest::ConfirmUIDs, &expected_uids), true); universe_uids.Clear(); universe->GetUIDs(&universe_uids); OLA_ASSERT_EQ(0u, universe_uids.Size()); universe->RemovePort(&port2); OLA_ASSERT_EQ((unsigned int) 0, universe->InputPortCount()); OLA_ASSERT_EQ((unsigned int) 0, universe->OutputPortCount()); OLA_ASSERT_FALSE(universe->IsActive()); }
/* * Check that HTP merging works correctly */ void UniverseTest::testHtpMerging() { DmxBuffer buffer1, buffer2, htp_buffer; buffer1.SetFromString("1,0,0,10"); buffer2.SetFromString("0,255,0,5,6,7"); htp_buffer.SetFromString("1,255,0,10,6,7"); ola::PortBroker broker; ola::PortManager port_manager(m_store, &broker); TimeStamp time_stamp; MockSelectServer ss(&time_stamp); ola::PluginAdaptor plugin_adaptor(NULL, &ss, NULL, NULL, NULL, NULL); MockDevice device(NULL, "foo"); MockDevice device2(NULL, "bar"); TestMockInputPort port(&device, 1, &plugin_adaptor); // input port TestMockInputPort port2(&device2, 1, &plugin_adaptor); // input port port_manager.PatchPort(&port, TEST_UNIVERSE); port_manager.PatchPort(&port2, TEST_UNIVERSE); Universe *universe = m_store->GetUniverseOrCreate(TEST_UNIVERSE); OLA_ASSERT(universe); universe->SetMergeMode(Universe::MERGE_HTP); OLA_ASSERT_EQ(universe->OutputPortCount(), (unsigned int) 0); OLA_ASSERT_EQ(universe->OutputPortCount(), (unsigned int) 0); OLA_ASSERT(universe->IsActive()); OLA_ASSERT_EQ((unsigned int) 0, universe->GetDMX().Size()); // Setup the ports with some data, and check that signalling the universe // works. m_clock.CurrentTime(&time_stamp); port.WriteDMX(buffer1); port.DmxChanged(); OLA_ASSERT_EQ(ola::dmx::SOURCE_PRIORITY_DEFAULT, universe->ActivePriority()); OLA_ASSERT_EQ(buffer1.Size(), universe->GetDMX().Size()); OLA_ASSERT(buffer1 == universe->GetDMX()); // Now the second port gets data m_clock.CurrentTime(&time_stamp); port2.WriteDMX(buffer2); port2.DmxChanged(); OLA_ASSERT_EQ(ola::dmx::SOURCE_PRIORITY_DEFAULT, universe->ActivePriority()); OLA_ASSERT_EQ(htp_buffer.Size(), universe->GetDMX().Size()); OLA_ASSERT(htp_buffer == universe->GetDMX()); // now raise the priority of the second port uint8_t new_priority = 120; port2.SetPriority(new_priority); m_clock.CurrentTime(&time_stamp); port2.DmxChanged(); OLA_ASSERT_EQ(new_priority, universe->ActivePriority()); OLA_ASSERT_EQ(buffer2.Size(), universe->GetDMX().Size()); OLA_ASSERT(buffer2 == universe->GetDMX()); // raise the priority of the first port port.SetPriority(new_priority); m_clock.CurrentTime(&time_stamp); port.DmxChanged(); OLA_ASSERT_EQ(new_priority, universe->ActivePriority()); OLA_ASSERT_EQ(htp_buffer.Size(), universe->GetDMX().Size()); OLA_ASSERT(htp_buffer == universe->GetDMX()); // now check a client DmxBuffer client_buffer; client_buffer.SetFromString("255,0,0,255,10"); m_clock.CurrentTime(&time_stamp); ola::DmxSource source(client_buffer, time_stamp, new_priority); MockClient input_client; input_client.DMXReceived(TEST_UNIVERSE, source); universe->SourceClientDataChanged(&input_client); DmxBuffer client_htp_merge_result; client_htp_merge_result.SetFromString("255,255,0,255,10,7"); OLA_ASSERT_EQ(new_priority, universe->ActivePriority()); OLA_ASSERT_EQ(client_htp_merge_result.Size(), universe->GetDMX().Size()); OLA_ASSERT(client_htp_merge_result == universe->GetDMX()); // clean up universe->RemoveSourceClient(&input_client); universe->RemovePort(&port); universe->RemovePort(&port2); OLA_ASSERT_FALSE(universe->IsActive()); }