* @brief Load the CEC adapter library.
* @param strDeviceName How to present this device to other devices.
* @param deviceTypes The device types to use on the CEC bus.
+ * @param iPhysicalAddress The physical address to assume on the bus. If set to 0, libCEC will try to autodetect the address, with the data provided via SetHDMIPort()
* @return An instance of ICECAdapter or NULL on error.
*/
-extern "C" DECLSPEC void * CECInit(const char *strDeviceName, CEC::cec_device_type_list devicesTypes);
+extern "C" DECLSPEC void * CECInit(const char *strDeviceName, CEC::cec_device_type_list devicesTypes, uint16_t iPhysicalAddress = 0);
/*!
* @brief Unload the CEC adapter library.
using namespace std;
using namespace PLATFORM;
-CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types) :
+CCECProcessor::CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types, uint16_t iPhysicalAddress /* = 0 */) :
m_bInitialised(false),
+ m_iPhysicalAddress(iPhysicalAddress),
m_iHDMIPort(CEC_DEFAULT_HDMI_PORT),
m_iBaseDevice((cec_logical_address)CEC_DEFAULT_BASE_DEVICE),
m_strDeviceName(strDeviceName),
m_busDevices[CECDEVICE_TV]->RequestVendorId();
ReplaceHandlers();
- if ((bReturn = SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true)) == false)
+ if (m_iPhysicalAddress != 0)
+ {
+ m_busDevices[m_logicalAddresses.primary]->m_iPhysicalAddress = m_iPhysicalAddress;
+ if ((bReturn = m_busDevices[m_logicalAddresses.primary]->TransmitPhysicalAddress()) == false)
+ CLibCEC::AddLog(CEC_LOG_ERROR, "unable to set the physical address to %4x", m_iPhysicalAddress);
+ }
+ else if (m_iPhysicalAddress == 0 && (bReturn = SetHDMIPort(m_iBaseDevice, m_iHDMIPort, true)) == false)
CLibCEC::AddLog(CEC_LOG_ERROR, "unable to set HDMI port %d on %s (%x)", m_iHDMIPort, ToString(m_iBaseDevice), (uint8_t)m_iBaseDevice);
SetInitialised(bReturn);
{
bool bReturn(false);
CLockObject lock(m_mutex);
+ if (m_iPhysicalAddress != 0)
+ {
+ CLibCEC::AddLog(CEC_LOG_WARNING, "ignoring SetHDMIPort() call because a physical address is set");
+ return bReturn;
+ }
m_iBaseDevice = iBaseDevice;
m_iHDMIPort = iPort;
{
CLockObject lock(m_mutex);
+ m_iPhysicalAddress = iPhysicalAddress;
+
if (!m_logicalAddresses.IsEmpty())
{
bool bWasActiveSource(false);
class CCECProcessor : public PLATFORM::CThread, public IAdapterCommunicationCallback
{
public:
- CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types);
+ CCECProcessor(CLibCEC *controller, const char *strDeviceName, const cec_device_type_list &types, uint16_t iPhysicalAddress = 0);
virtual ~CCECProcessor(void);
virtual bool Start(const char *strPort, uint16_t iBaudRate = 38400, uint32_t iTimeoutMs = 10000);
void ParseCommand(const cec_command &command);
bool m_bInitialised;
+ uint16_t m_iPhysicalAddress;
uint8_t m_iHDMIPort;
cec_logical_address m_iBaseDevice;
cec_logical_addresses m_logicalAddresses;
using namespace CEC;
using namespace PLATFORM;
-CLibCEC::CLibCEC(const char *strDeviceName, cec_device_type_list types) :
+CLibCEC::CLibCEC(const char *strDeviceName, cec_device_type_list types, uint16_t iPhysicalAddress /* = 0 */) :
m_iStartTime(GetTimeMs()),
m_iCurrentButton(CEC_USER_CONTROL_CODE_UNKNOWN),
m_buttontime(0),
m_callbacks(NULL),
m_cbParam(NULL)
{
- m_cec = new CCECProcessor(this, strDeviceName, types);
+ m_cec = new CCECProcessor(this, strDeviceName, types, iPhysicalAddress);
}
CLibCEC::~CLibCEC(void)
g_libCEC_instance = instance;
}
-void * CECInit(const char *strDeviceName, CEC::cec_device_type_list types)
+void * CECInit(const char *strDeviceName, CEC::cec_device_type_list types, uint16_t iPhysicalAddress /* = 0 */)
{
CLibCEC *lib = new CLibCEC(strDeviceName, types);
CLibCEC::SetInstance(lib);
* ICECAdapter implementation
*/
//@{
- CLibCEC(const char *strDeviceName, cec_device_type_list types);
+ CLibCEC(const char *strDeviceName, cec_device_type_list types, uint16_t iPhysicalAddress = 0);
virtual ~CLibCEC(void);
virtual bool Open(const char *strPort, uint32_t iTimeout = 10000);