/*!
* @brief Changes the active HDMI port.
+ * @param iBaseDevice The device to which this libcec is connected.
* @param iPort The new port number.
* @return True when changed, false otherwise.
*/
- virtual bool SetHDMIPort(uint8_t iPort) = 0;
+ virtual bool SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort) = 0;
/*!
* @brief Sends a volume up keypress to an audiosystem if it's present.
extern DECLSPEC int cec_is_active_device_type(cec_device_type type);
#endif
-extern DECLSPEC int cec_set_hdmi_port(uint8_t iPort);
+#ifdef __cplusplus
+extern DECLSPEC int cec_set_hdmi_port(CEC::cec_logical_address iBaseDevice, uint8_t iPort);
+#else
+extern DECLSPEC int cec_set_hdmi_port(cec_logical_address iBaseDevice, uint8_t iPort);
+#endif
extern DECLSPEC int cec_volume_up(int bWait);
//default physical address 1.0.0.0, HDMI port 1
#define CEC_DEFAULT_PHYSICAL_ADDRESS 0x1000
#define CEC_DEFAULT_HDMI_PORT 1
+#define CEC_DEFAULT_BASE_DEVICE 0
#define MSGSTART 0xFF
#define MSGEND 0xFE
#define MSGESC 0xFD
CCECProcessor::CCECProcessor(CLibCEC *controller, CAdapterCommunication *serComm, const char *strDeviceName, cec_logical_address iLogicalAddress /* = CECDEVICE_PLAYBACKDEVICE1 */, uint16_t iPhysicalAddress /* = CEC_DEFAULT_PHYSICAL_ADDRESS*/) :
m_bStarted(false),
m_iHDMIPort(CEC_DEFAULT_HDMI_PORT),
+ m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
m_strDeviceName(strDeviceName),
m_communication(serComm),
m_controller(controller),
CCECProcessor::CCECProcessor(CLibCEC *controller, CAdapterCommunication *serComm, const char *strDeviceName, const cec_device_type_list &types) :
m_bStarted(false),
m_iHDMIPort(CEC_DEFAULT_HDMI_PORT),
+ m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
m_strDeviceName(strDeviceName),
m_types(types),
m_communication(serComm),
lock.Leave();
if (SetAckMask(m_logicalAddresses.AckMask()) &&
- SetHDMIPort(m_iHDMIPort, true))
+ SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true))
{
m_busScan = new CCECBusScan(this);
m_busScan->CreateThread(true);
return bReturn;
}
-bool CCECProcessor::SetHDMIPort(uint8_t iPort, bool bForce /* = false */)
+bool CCECProcessor::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort, bool bForce /* = false */)
{
bool bReturn(false);
CStdString strLog;
- strLog.Format("setting HDMI port to %d", iPort);
+ strLog.Format("setting HDMI port to %d on device %s (%d)", iPort, ToString(iBaseDevice), (int)iBaseDevice);
AddLog(CEC_LOG_DEBUG, strLog);
+ m_iBaseDevice = iBaseDevice;
m_iHDMIPort = iPort;
if (!m_bStarted && !bForce)
return true;
uint16_t iPhysicalAddress(0);
- int iPos = 3;
- while(!bReturn && iPos >= 0)
+ iPhysicalAddress = m_busDevices[iBaseDevice]->GetPhysicalAddress();
+ uint16_t iPos = 0;
+ if (iPhysicalAddress == 0)
+ iPos = 0x1000;
+ else if (iPhysicalAddress % 0x1000 == 0)
+ iPos = 0x100;
+ else if (iPhysicalAddress % 0x100 == 0)
+ iPos = 0x10;
+ else if (iPhysicalAddress % 0x10 == 0)
+ iPos = 0x1;
+
+ while(!bReturn && iPos > 0)
{
- iPhysicalAddress += ((uint16_t)iPort * (0x1 << iPos*4));
+ iPhysicalAddress += (uint16_t)(iPort * iPos);
strLog.Format("checking physical address %4x", iPhysicalAddress);
AddLog(CEC_LOG_DEBUG, strLog);
if (CheckPhysicalAddress(iPhysicalAddress))
{
strLog.Format("physical address %4x is in use", iPhysicalAddress);
AddLog(CEC_LOG_DEBUG, strLog);
- iPos--;
+ iPos = (iPos == 1) ? 0 : iPos / 0x10;
}
else
{
virtual bool SetActiveSource(cec_logical_address iAddress);
virtual bool SetDeckControlMode(cec_deck_control_mode mode, bool bSendUpdate = true);
virtual bool SetDeckInfo(cec_deck_info info, bool bSendUpdate = true);
- virtual bool SetHDMIPort(uint8_t iPort, bool bForce = false);
+ virtual bool SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort, bool bForce = false);
virtual bool TransmitInactiveSource(void);
virtual bool SetLogicalAddress(cec_logical_address iLogicalAddress);
virtual bool SetMenuState(cec_menu_state state, bool bSendUpdate = true);
bool m_bStarted;
uint8_t m_iHDMIPort;
+ cec_logical_address m_iBaseDevice;
cec_command m_currentframe;
cec_logical_addresses m_logicalAddresses;
std::string m_strDeviceName;
return m_cec ? m_cec->SetPhysicalAddress(iPhysicalAddress) : false;
}
-bool CLibCEC::SetHDMIPort(uint8_t iPort /* = CEC_DEFAULT_HDMI_PORT */)
+bool CLibCEC::SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort /* = CEC_DEFAULT_HDMI_PORT */)
{
- return m_cec ? m_cec->SetHDMIPort(iPort) : false;
+ return m_cec ? m_cec->SetHDMIPort(iBaseDevice, iPort) : false;
}
bool CLibCEC::PowerOnDevices(cec_logical_address address /* = CECDEVICE_TV */)
virtual cec_logical_addresses GetActiveDevices(void);
virtual bool IsActiveDevice(cec_logical_address iAddress);
virtual bool IsActiveDeviceType(cec_device_type type);
- virtual bool SetHDMIPort(uint8_t iPort = CEC_DEFAULT_HDMI_PORT);
+ virtual bool SetHDMIPort(cec_logical_address iBaseDevice, uint8_t iPort = CEC_DEFAULT_HDMI_PORT);
virtual uint8_t VolumeUp(bool bWait = true);
virtual uint8_t VolumeDown(bool bWait = true);
virtual uint8_t MuteAudio(bool bWait = true);
return -1;
}
-int cec_set_hdmi_port(uint8_t iPort)
+int cec_set_hdmi_port(cec_logical_address iBaseDevice, uint8_t iPort)
{
if (cec_parser)
- return cec_parser->SetHDMIPort(iPort) ? 1 : 0;
+ return cec_parser->SetHDMIPort(iBaseDevice, iPort) ? 1 : 0;
return -1;
}
"[on] {address} power on the device with the given logical address." << endl <<
"[standby] {address} put the device with the given address in standby mode." << endl <<
"[la] {logical address} change the logical address of the CEC adapter." << endl <<
- "[p] {port number} change the HDMI port number of the CEC adapter." << endl <<
+ "[p] {device} {port} change the HDMI port number of the CEC adapter." << endl <<
"[pa] {physical address} change the physical address of the CEC adapter." << endl <<
"[osd] {addr} {string} set OSD message on the specified device." << endl <<
"[ver] {addr} get the CEC version of the specified device." << endl <<
if (iHDMIPort > 0)
{
- parser->SetHDMIPort((uint8_t)iHDMIPort);
+ parser->SetHDMIPort((cec_logical_address)CEC_DEFAULT_BASE_DEVICE, (uint8_t)iHDMIPort);
FlushLog(parser);
}
}
else if (command == "p")
{
- string strvalue;
- if (GetWord(input, strvalue))
+ string strPort, strDevice;
+ if (GetWord(input, strDevice) && GetWord(input, strPort))
{
- parser->SetHDMIPort((uint8_t)atoi(strvalue.c_str()));
+ parser->SetHDMIPort((cec_logical_address)atoi(strDevice.c_str()), (uint8_t)atoi(strPort.c_str()));
}
}
else if (command == "pa")