bool CCECProcessor::AllocateLogicalAddresses(CECClientPtr client) { libcec_configuration &configuration = *client->GetConfiguration(); // mark as unregistered client->SetRegistered(false); // unregister this client from the old addresses CECDEVICEVEC devices; m_busDevices->GetByLogicalAddresses(devices, configuration.logicalAddresses); for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) { // remove client entry CLockObject lock(m_mutex); m_clients.erase((*it)->GetLogicalAddress()); } // find logical addresses for this client if (!client->AllocateLogicalAddresses()) { m_libcec->AddLog(CEC_LOG_ERROR, "failed to find a free logical address for the client"); return false; } // refresh the address if (configuration.bAutodetectAddress) client->AutodetectPhysicalAddress(); // register this client on the new addresses devices.clear(); m_busDevices->GetByLogicalAddresses(devices, configuration.logicalAddresses); for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) { // set the physical address of the device at this LA if (CLibCEC::IsValidPhysicalAddress(configuration.iPhysicalAddress)) (*it)->SetPhysicalAddress(configuration.iPhysicalAddress); // replace a previous client CLockObject lock(m_mutex); m_clients.erase((*it)->GetLogicalAddress()); m_clients.insert(make_pair((*it)->GetLogicalAddress(), client)); } // set the new ackmask SetLogicalAddresses(GetLogicalAddresses()); // resume outgoing communication m_bStallCommunication = false; return true; }
bool CCECProcessor::PowerOnDevices(const cec_logical_address initiator, const CECDEVICEVEC &devices) { bool bReturn(true); for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) bReturn &= (*it)->PowerOn(initiator); return bReturn; }
std::string CCECClient::GetConnectionInfo(void) { CStdString strLog; strLog.Format("libCEC version = %s, client version = %s, firmware version = %d", ToString((cec_server_version)m_configuration.serverVersion), ToString((cec_client_version)m_configuration.clientVersion), m_configuration.iFirmwareVersion); if (m_configuration.iFirmwareBuildDate != CEC_FW_BUILD_UNKNOWN) { time_t buildTime = (time_t)m_configuration.iFirmwareBuildDate; strLog.AppendFormat(", firmware build date: %s", asctime(gmtime(&buildTime))); strLog = strLog.Left((int)strLog.length() - 1); // strip \n added by asctime strLog.append(" +0000"); } // log the addresses that are being used if (!m_configuration.logicalAddresses.IsEmpty()) { strLog.append(", logical address(es) = "); CECDEVICEVEC devices; m_processor->GetDevices()->GetByLogicalAddresses(devices, m_configuration.logicalAddresses); for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++) strLog.AppendFormat("%s (%X) ", (*it)->GetLogicalAddressName(), (*it)->GetLogicalAddress()); } if (!CLibCEC::IsValidPhysicalAddress(m_configuration.iPhysicalAddress)) strLog.AppendFormat(", base device: %s (%X), HDMI port number: %d", ToString(m_configuration.baseDevice), m_configuration.baseDevice, m_configuration.iHDMIPort); else strLog.AppendFormat(", physical address: %04x", m_configuration.iPhysicalAddress); strLog.AppendFormat(", %s", LIB_CEC->GetLibInfo()); std::string strReturn(strLog.c_str()); return strReturn; }
cec_logical_addresses CCECDeviceMap::ToLogicalAddresses(const CECDEVICEVEC &devices) { cec_logical_addresses addresses; addresses.Clear(); for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) addresses.Set((*it)->GetLogicalAddress()); return addresses; }
void CCECDeviceMap::FilterType(const cec_device_type type, CECDEVICEVEC &devices) { CECDEVICEVEC newDevices; for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) { if ((*it)->GetType() == type) newDevices.push_back(*it); } devices = newDevices; }
void CCECDeviceMap::FilterLibCECControlled(CECDEVICEVEC &devices) { CECDEVICEVEC newDevices; for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) { if ((*it)->IsHandledByLibCEC()) newDevices.push_back(*it); } devices = newDevices; }
void CCECDeviceMap::FilterTypes(const cec_device_type_list &types, CECDEVICEVEC &devices) { cec_device_type_list t(types);//silly, but needed to retain abi CECDEVICEVEC newDevices; for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) { if (t.IsSet((*it)->GetType())) newDevices.push_back(*it); } devices = newDevices; }
void CCECDeviceMap::FilterActive(CECDEVICEVEC &devices) { CECDEVICEVEC newDevices; for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) { cec_bus_device_status status = (*it)->GetCurrentStatus(); if (status == CEC_DEVICE_STATUS_HANDLED_BY_LIBCEC || status == CEC_DEVICE_STATUS_PRESENT) newDevices.push_back(*it); } devices = newDevices; }
bool CCECClient::SendSetMenuState(const cec_menu_state state, bool bSendUpdate /* = true */) { CECDEVICEVEC devices; // set the menu state for all devices that are controlled by us m_processor->GetDevices()->GetByLogicalAddresses(devices, m_configuration.logicalAddresses); for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++) { (*it)->SetMenuState(state); if (bSendUpdate) (*it)->TransmitMenuState(CECDEVICE_TV, false); } return true; }
bool CCECClient::SendSetInactiveView(void) { CECDEVICEVEC devices; // mark all devices that are controlled by us as inactive source m_processor->GetDevices()->GetByLogicalAddresses(devices, m_configuration.logicalAddresses); for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++) { if ((*it)->IsActiveSource()) { (*it)->MarkAsInactiveSource(); return (*it)->TransmitInactiveSource(); } } return true; }
bool CCECClient::SetDevicePhysicalAddress(const uint16_t iPhysicalAddress) { if (!CLibCEC::IsValidPhysicalAddress(iPhysicalAddress)) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - not setting invalid physical address %04x", __FUNCTION__, iPhysicalAddress); return false; } // reconfigure all devices cec_logical_address reactivateSource(CECDEVICE_UNKNOWN); CECDEVICEVEC devices; m_processor->GetDevices()->GetByLogicalAddresses(devices, m_configuration.logicalAddresses); for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++) { // if this device was the active source, reactivate it afterwards if ((*it)->IsActiveSource()) reactivateSource = (*it)->GetLogicalAddress(); // mark the device as inactive source if (IsInitialised()) (*it)->MarkAsInactiveSource(); // set the new physical address (*it)->SetPhysicalAddress(iPhysicalAddress); // and transmit it if (IsInitialised()) (*it)->TransmitPhysicalAddress(false); } // reactivate the previous active source if (reactivateSource != CECDEVICE_UNKNOWN && m_processor->CECInitialised() && IsInitialised()) { CCECBusDevice *device = m_processor->GetDevice(reactivateSource); if (device) device->ActivateSource(); } // persist the new configuration PersistConfiguration(m_configuration); return true; }
bool CCECProcessor::UnregisterClient(CCECClient *client) { if (!client) return false; if (client->IsRegistered()) m_libcec->AddLog(CEC_LOG_NOTICE, "unregistering client: %s", client->GetConnectionInfo().c_str()); // notify the client that it will be unregistered client->OnUnregister(); { CLockObject lock(m_mutex); // find all devices that match the LA's of this client CECDEVICEVEC devices; m_busDevices->GetByLogicalAddresses(devices, client->GetConfiguration()->logicalAddresses); for (CECDEVICEVEC::const_iterator it = devices.begin(); it != devices.end(); it++) { // find the client map<cec_logical_address, CCECClient *>::iterator entry = m_clients.find((*it)->GetLogicalAddress()); // unregister the client if (entry != m_clients.end()) m_clients.erase(entry); // reset the device status (*it)->ResetDeviceStatus(true); } } // set the new ackmask cec_logical_addresses addresses = GetLogicalAddresses(); if (SetLogicalAddresses(addresses)) { // no more clients left, disable controlled mode if (addresses.IsEmpty() && !m_bMonitor) m_communication->SetControlledMode(false); return true; } return false; }
void CCECBusDevice::MarkAsActiveSource(void) { bool bWasActivated(false); // set the power status to powered on SetPowerStatus(CEC_POWER_STATUS_ON); // mark this device as active source { CLockObject lock(m_mutex); if (!m_bActiveSource) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "making %s (%x) the active source", GetLogicalAddressName(), m_iLogicalAddress); bWasActivated = true; } else LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s (%x) was already marked as active source", GetLogicalAddressName(), m_iLogicalAddress); m_bActiveSource = true; } CCECBusDevice* tv = m_processor->GetDevice(CECDEVICE_TV); if (tv) tv->OnImageViewOnSent(false); // mark other devices as inactive sources CECDEVICEVEC devices; m_processor->GetDevices()->Get(devices); for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++) if ((*it)->GetLogicalAddress() != m_iLogicalAddress) (*it)->MarkAsInactiveSource(); if (bWasActivated) { if (IsHandledByLibCEC()) m_processor->SetActiveSource(true, false); CCECClient *client = GetClient(); if (client) client->SourceActivated(m_iLogicalAddress); } }
bool CCECClient::OnRegister(void) { // return false if already initialised if (IsInitialised()) return true; // get all device we control CECDEVICEVEC devices; m_processor->GetDevices()->GetByLogicalAddresses(devices, m_configuration.logicalAddresses); // return false when no devices were found if (devices.empty()) { LIB_CEC->AddLog(CEC_LOG_WARNING, "cannot find the primary device (logical address %x)", GetPrimaryLogicalAdddress()); return false; } // mark as initialised SetInitialised(true); // configure all devices for (CECDEVICEVEC::iterator it = devices.begin(); it != devices.end(); it++) { // only set our OSD name for the primary device if ((*it)->GetLogicalAddress() == GetPrimaryLogicalAdddress()) (*it)->SetOSDName(m_configuration.strDeviceName); // set the default menu language for devices we control (*it)->SetMenuLanguage(m_configuration.strDeviceLanguage); } // set the physical address SetPhysicalAddress(m_configuration); // make the primary device the active source if the option is set if (m_configuration.bActivateSource == 1) GetPrimaryDevice()->ActivateSource(500); return true; }