From 092c0010eee4053d61ba76e011e650013935883a Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 8 Apr 2025 11:27:58 -0400 Subject: [PATCH 01/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 3315 +------------------- HdmiCecSink/HdmiCecSink.h | 881 ++---- HdmiCecSink/HdmiCecSinkImplementation.cpp | 3401 +++++++++++++++++++++ HdmiCecSink/HdmiCecSinkImplementation.h | 748 +++++ 4 files changed, 4407 insertions(+), 3938 deletions(-) create mode 100644 HdmiCecSink/HdmiCecSinkImplementation.cpp create mode 100644 HdmiCecSink/HdmiCecSinkImplementation.h diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 7c50d696..aea2cc56 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -105,73 +105,12 @@ enum { }; -enum { - HDMICECSINK_EVENT_ACTIVE_SOURCE_CHANGE = 1, - HDMICECSINK_EVENT_WAKEUP_FROM_STANDBY, - HDMICECSINK_EVENT_TEXT_VIEW_ON_MSG, - HDMICECSINK_EVENT_IMAGE_VIEW_ON_MSG, - HDMICECSINK_EVENT_DEVICE_ADDED, - HDMICECSINK_EVENT_DEVICE_REMOVED, - HDMICECSINK_EVENT_DEVICE_INFO_UPDATED, - HDMICECSINK_EVENT_INACTIVE_SOURCE, - HDMICECSINK_EVENT_ARC_INITIATION_EVENT, - HDMICECSINK_EVENT_ARC_TERMINATION_EVENT, - HDMICECSINK_EVENT_SHORT_AUDIODESCRIPTOR_EVENT, - HDMICECSINK_EVENT_STANDBY_MSG_EVENT, - HDMICECSINK_EVENT_SYSTEM_AUDIO_MODE, - HDMICECSINK_EVENT_REPORT_AUDIO_STATUS, - HDMICECSINK_EVENT_AUDIO_DEVICE_CONNECTED_STATUS, - HDMICECSINK_EVENT_CEC_ENABLED, - HDMICECSINK_EVENT_AUDIO_DEVICE_POWER_STATUS, - HDMICECSINK_EVENT_FEATURE_ABORT_EVENT, -}; - -static const char *eventString[] = { - "None", - "onActiveSourceChange", - "onWakeupFromStandby", - "onTextViewOnMsg", - "onImageViewOnMsg", - "onDeviceAdded", - "onDeviceRemoved", - "onDeviceInfoUpdated", - "onInActiveSource", - "arcInitiationEvent", - "arcTerminationEvent", - "shortAudiodesciptorEvent", - "standbyMessageReceived", - "setSystemAudioModeEvent", - "reportAudioStatusEvent", - "reportAudioDeviceConnectedStatus", - "reportCecEnabledEvent", - "reportAudioDevicePowerStatus", - "reportFeatureAbortEvent" -}; - - #define CEC_SETTING_ENABLED_FILE "/opt/persistent/ds/cecData_2.json" #define CEC_SETTING_OTP_ENABLED "cecOTPEnabled" #define CEC_SETTING_ENABLED "cecEnabled" #define CEC_SETTING_OSD_NAME "cecOSDName" #define CEC_SETTING_VENDOR_ID "cecVendorId" -static std::vector defaultVendorId = {0x00,0x19,0xFB}; -static VendorID appVendorId = {defaultVendorId.at(0),defaultVendorId.at(1),defaultVendorId.at(2)}; -static VendorID lgVendorId = {0x00,0xE0,0x91}; -static PhysicalAddress physical_addr = {0x0F,0x0F,0x0F,0x0F}; -static LogicalAddress logicalAddress = 0xF; -static Language defaultLanguage = "eng"; -static OSDName osdName = "TV Box"; -static int32_t powerState = DEVICE_POWER_STATE_OFF; -static std::vector formatid = {0,0}; -static std::vector audioFormatCode = { SAD_FMT_CODE_ENHANCED_AC3,SAD_FMT_CODE_AC3 }; -static uint8_t numberofdescriptor = 2; -static int32_t HdmiArcPortID = -1; -static float cecVersion = 1.4; -static AllDeviceTypes allDevicetype = ALL_DEVICE_TYPES; -static std::vector rcProfile = {RC_PROFILE_TV}; -static std::vector deviceFeatures = {DEVICE_FEATURES_TV}; - #define API_VERSION_NUMBER_MAJOR 1 #define API_VERSION_NUMBER_MINOR 3 #define API_VERSION_NUMBER_PATCH 7 @@ -201,483 +140,7 @@ namespace WPEFramework HdmiCecSink* HdmiCecSink::_instance = nullptr; static int libcecInitStatus = 0; -//=========================================== HdmiCecSinkFrameListener ========================================= - void HdmiCecSinkFrameListener::notify(const CECFrame &in) const { - const uint8_t *buf = NULL; - char strBuffer[512] = {0}; - size_t len = 0; - - in.getBuffer(&buf, &len); - for (unsigned int i = 0; i < len; i++) { - snprintf(strBuffer + (i*3) , sizeof(strBuffer) - (i*3), "%02X ",(uint8_t) *(buf + i)); - } - LOGINFO(" >>>>> Received CEC Frame: :%s \n",strBuffer); - - MessageDecoder(processor).decode(in); - } - -//=========================================== HdmiCecSinkProcessor ========================================= - void HdmiCecSinkProcessor::process (const ActiveSource &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: ActiveSource %s : %s : %s \n",GetOpName(msg.opCode()),msg.physicalAddress.name().c_str(),msg.physicalAddress.toString().c_str()); - if(!(header.to == LogicalAddress(LogicalAddress::BROADCAST))){ - LOGINFO("Ignore Direct messages, accepts only broadcast messages"); - return; - } - HdmiCecSink::_instance->addDevice(header.from.toInt()); - HdmiCecSink::_instance->updateActiveSource(header.from.toInt(), msg); - } - void HdmiCecSinkProcessor::process (const InActiveSource &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: InActiveSource %s : %s : %s \n",GetOpName(msg.opCode()),msg.physicalAddress.name().c_str(),msg.physicalAddress.toString().c_str()); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - - HdmiCecSink::_instance->updateInActiveSource(header.from.toInt(), msg); - } - - void HdmiCecSinkProcessor::process (const ImageViewOn &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: ImageViewOn from %s\n", header.from.toString().c_str()); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - HdmiCecSink::_instance->addDevice(header.from.toInt()); - HdmiCecSink::_instance->updateImageViewOn(header.from.toInt()); - } - void HdmiCecSinkProcessor::process (const TextViewOn &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: TextViewOn\n"); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - HdmiCecSink::_instance->addDevice(header.from.toInt()); - HdmiCecSink::_instance->updateTextViewOn(header.from.toInt()); - } - void HdmiCecSinkProcessor::process (const RequestActiveSource &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: RequestActiveSource\n"); - if(!(header.to == LogicalAddress(LogicalAddress::BROADCAST))){ - LOGINFO("Ignore Direct messages, accepts only broadcast messages"); - return; - } - - HdmiCecSink::_instance->setActiveSource(true); - } - void HdmiCecSinkProcessor::process (const Standby &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: Standby from %s\n", header.from.toString().c_str()); - HdmiCecSink::_instance->SendStandbyMsgEvent(header.from.toInt()); - } - void HdmiCecSinkProcessor::process (const GetCECVersion &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: GetCECVersion sending CECVersion response \n"); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - try - { - if(cecVersion == 2.0) { - conn.sendToAsync(header.from, MessageEncoder().encode(CECVersion(Version::V_2_0))); - } - else{ - conn.sendToAsync(header.from, MessageEncoder().encode(CECVersion(Version::V_1_4))); - } - } - catch(...) - { - LOGWARN("Exception while sending CECVersion "); - } - } - void HdmiCecSinkProcessor::process (const CECVersion &msg, const Header &header) - { - bool updateStatus; - printHeader(header); - LOGINFO("Command: CECVersion Version : %s \n",msg.version.toString().c_str()); - - HdmiCecSink::_instance->addDevice(header.from.toInt()); - updateStatus = HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isVersionUpdated; - LOGINFO("updateStatus %d\n",updateStatus); - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(msg.version); - if(!updateStatus) - HdmiCecSink::_instance->sendDeviceUpdateInfo(header.from.toInt()); - } - void HdmiCecSinkProcessor::process (const SetMenuLanguage &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: SetMenuLanguage Language : %s \n",msg.language.toString().c_str()); - } - void HdmiCecSinkProcessor::process (const GiveOSDName &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: GiveOSDName sending SetOSDName : %s\n",osdName.toString().c_str()); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - try - { - conn.sendToAsync(header.from, MessageEncoder().encode(SetOSDName(osdName))); - } - catch(...) - { - LOGWARN("Exception while sending SetOSDName"); - } - } - void HdmiCecSinkProcessor::process (const GivePhysicalAddress &msg, const Header &header) - { - LOGINFO("Command: GivePhysicalAddress\n"); - if (!(header.to == LogicalAddress(LogicalAddress::BROADCAST))) - { - try - { - LOGINFO(" sending ReportPhysicalAddress response physical_addr :%s logicalAddress :%x \n",physical_addr.toString().c_str(), logicalAddress.toInt()); - conn.sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(ReportPhysicalAddress(physical_addr,logicalAddress.toInt())), 500); - } - catch(...) - { - LOGWARN("Exception while sending ReportPhysicalAddress "); - } - } - } - void HdmiCecSinkProcessor::process (const GiveDeviceVendorID &msg, const Header &header) - { - printHeader(header); - if(header.to == LogicalAddress(LogicalAddress::BROADCAST)){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - try - { - LOGINFO("Command: GiveDeviceVendorID sending VendorID response :%s\n",appVendorId.toString().c_str()); - conn.sendToAsync(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(DeviceVendorID(appVendorId))); - } - catch(...) - { - LOGWARN("Exception while sending DeviceVendorID"); - } - - } - void HdmiCecSinkProcessor::process (const SetOSDString &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: SetOSDString OSDString : %s\n",msg.osdString.toString().c_str()); - } - void HdmiCecSinkProcessor::process (const SetOSDName &msg, const Header &header) - { - printHeader(header); - bool updateStatus ; - LOGINFO("Command: SetOSDName OSDName : %s\n",msg.osdName.toString().c_str()); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - - HdmiCecSink::_instance->addDevice(header.from.toInt()); - updateStatus = HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isOSDNameUpdated; - LOGINFO("updateStatus %d\n",updateStatus); - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(msg.osdName); - if(HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isRequestRetry > 0 && - HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isRequested == CECDeviceParams::REQUEST_OSD_NAME) { - HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isRequestRetry = 0; - } - if(!updateStatus) - HdmiCecSink::_instance->sendDeviceUpdateInfo(header.from.toInt()); - } - void HdmiCecSinkProcessor::process (const RoutingChange &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: RoutingChange From : %s To: %s \n",msg.from.toString().c_str(),msg.to.toString().c_str()); - } - void HdmiCecSinkProcessor::process (const RoutingInformation &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: RoutingInformation Routing Information to Sink : %s\n",msg.toSink.toString().c_str()); - } - void HdmiCecSinkProcessor::process (const SetStreamPath &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: SetStreamPath Set Stream Path to Sink : %s\n",msg.toSink.toString().c_str()); - } - void HdmiCecSinkProcessor::process (const GetMenuLanguage &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: GetMenuLanguage\n"); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - HdmiCecSink::_instance->sendMenuLanguage(); - } - void HdmiCecSinkProcessor::process (const ReportPhysicalAddress &msg, const Header &header) - { - printHeader(header); - bool updateDeviceTypeStatus; - bool updatePAStatus; - LOGINFO("Command: ReportPhysicalAddress\n"); - if(!(header.to == LogicalAddress(LogicalAddress::BROADCAST))){ - LOGINFO("Ignore Direct messages, accepts only broadcast messages"); - return; - } - - if(!HdmiCecSink::_instance) - return; - HdmiCecSink::_instance->addDevice(header.from.toInt()); - updateDeviceTypeStatus = HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isDeviceTypeUpdated; - updatePAStatus = HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isPAUpdated; - LOGINFO("updateDeviceTypeStatus %d updatePAStatus %d \n",updateDeviceTypeStatus,updatePAStatus); - if(HdmiCecSink::_instance->deviceList[header.from.toInt()].m_physicalAddr.toString() != msg.physicalAddress.toString() && updatePAStatus){ - updatePAStatus= false; - LOGINFO("There is a change in physical address from current PA %s to newly reported PA %s\n",HdmiCecSink::_instance->deviceList[header.from.toInt()].m_physicalAddr.toString().c_str(),msg.physicalAddress.toString().c_str()); - } - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(msg.physicalAddress); - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(msg.deviceType); - if(HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isRequestRetry > 0 && - HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isRequested == CECDeviceParams::REQUEST_PHISICAL_ADDRESS) { - HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isRequestRetry = 0; - } - HdmiCecSink::_instance->updateDeviceChain(header.from, msg.physicalAddress); - if (!updateDeviceTypeStatus || !updatePAStatus) - HdmiCecSink::_instance->sendDeviceUpdateInfo(header.from.toInt()); - } - void HdmiCecSinkProcessor::process (const DeviceVendorID &msg, const Header &header) - { - bool updateStatus ; - printHeader(header); - LOGINFO("Command: DeviceVendorID VendorID : %s\n",msg.vendorId.toString().c_str()); - if(!(header.to == LogicalAddress(LogicalAddress::BROADCAST))){ - LOGINFO("Ignore Direct messages, accepts only broadcast messages"); - return; - } - - HdmiCecSink::_instance->addDevice(header.from.toInt()); - updateStatus = HdmiCecSink::_instance->deviceList[header.from.toInt()].m_isVendorIDUpdated; - LOGINFO("updateStatus %d\n",updateStatus); - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(msg.vendorId); - if (!updateStatus) - HdmiCecSink::_instance->sendDeviceUpdateInfo(header.from.toInt()); - } - void HdmiCecSinkProcessor::process (const GiveDevicePowerStatus &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: GiveDevicePowerStatus sending powerState :%d \n",powerState); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - try - { - conn.sendTo(header.from, MessageEncoder().encode(ReportPowerStatus(PowerStatus(powerState)))); - } - catch(...) - { - LOGWARN("Exception while sending ReportPowerStatus"); - } - } - void HdmiCecSinkProcessor::process (const ReportPowerStatus &msg, const Header &header) - { - uint32_t oldPowerStatus,newPowerStatus; - printHeader(header); - LOGINFO("Command: ReportPowerStatus Power Status from:%s status : %s \n",header.from.toString().c_str(),msg.status.toString().c_str()); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - oldPowerStatus = HdmiCecSink::_instance->deviceList[header.from.toInt()].m_powerStatus.toInt(); - HdmiCecSink::_instance->addDevice(header.from.toInt()); - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(msg.status); - newPowerStatus = HdmiCecSink::_instance->deviceList[header.from.toInt()].m_powerStatus.toInt(); - LOGINFO(" oldPowerStatus %d newpower status %d \n",oldPowerStatus,newPowerStatus); - if ((oldPowerStatus != newPowerStatus) ) - { - HdmiCecSink::_instance->sendDeviceUpdateInfo(header.from.toInt()); - } - - if((header.from.toInt() == LogicalAddress::AUDIO_SYSTEM) && (HdmiCecSink::_instance->m_audioDevicePowerStatusRequested)) { - HdmiCecSink::_instance->reportAudioDevicePowerStatusInfo(header.from.toInt(), newPowerStatus); - } - - } - void HdmiCecSinkProcessor::process (const FeatureAbort &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: FeatureAbort opcode=%s, Reason = %s\n", msg.feature.toString().c_str(), msg.reason.toString().c_str()); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - - if(header.from.toInt() < LogicalAddress::UNREGISTERED && - msg.reason.toInt() == AbortReason::UNRECOGNIZED_OPCODE) - { - switch(msg.feature.opCode()) - { - case GET_CEC_VERSION : - { - /* If we get a Feature abort for CEC Version then default to 1.4b */ - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(Version(Version::V_1_4)); - } - break; - case GIVE_DEVICE_VENDOR_ID : - { - /* If we get a Feature abort for CEC Version then default to 1.4b */ - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(VendorID((uint8_t *)"FA", 2)); - } - break; - - case GIVE_OSD_NAME : - { - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(OSDName("")); - } - break; - - case GIVE_DEVICE_POWER_STATUS : - { - HdmiCecSink::_instance->deviceList[header.from.toInt()].update(PowerStatus(PowerStatus::POWER_STATUS_FEATURE_ABORT)); - } - break; - } - - HdmiCecSink::_instance->deviceList[header.from.toInt()].m_featureAborts.push_back(msg); - } - - LogicalAddress logicaladdress = header.from.toInt(); - OpCode featureOpcode = msg.feature; - AbortReason abortReason = msg.reason; - - HdmiCecSink::_instance->reportFeatureAbortEvent(logicaladdress,featureOpcode,abortReason); - - if(msg.feature.opCode() == REQUEST_SHORT_AUDIO_DESCRIPTOR) - { - JsonArray audiodescriptor; - audiodescriptor.Add(0); - HdmiCecSink::_instance->Send_ShortAudioDescriptor_Event(audiodescriptor); - } - - } - void HdmiCecSinkProcessor::process (const Abort &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: Abort\n"); - if (!(header.to == LogicalAddress(LogicalAddress::BROADCAST))) - { - AbortReason reason = AbortReason::UNRECOGNIZED_OPCODE; - LogicalAddress logicaladdress =header.from.toInt(); - OpCode feature = msg.opCode(); - HdmiCecSink::_instance->sendFeatureAbort(logicaladdress, feature,reason); - } - else - { - LOGINFO("Command: Abort broadcast msg so ignore\n"); - } - } - void HdmiCecSinkProcessor::process (const Polling &msg, const Header &header) { - printHeader(header); - LOGINFO("Command: Polling\n"); - } - - void HdmiCecSinkProcessor::process (const InitiateArc &msg, const Header &header) - { - printHeader(header); - if((!(header.from.toInt() == 0x5)) || (header.to.toInt() == LogicalAddress::BROADCAST)){ - LOGINFO("Ignoring the message coming from addresses other than 0X5 or a braodcast message"); - return; - } - PhysicalAddress physical_addr_invalid = {0x0F,0x0F,0x0F,0x0F}; - PhysicalAddress physical_addr_arc_port = {0x0F,0x0F,0x0F,0x0F}; - - LOGINFO("Command: INITIATE_ARC \n"); - if(!HdmiCecSink::_instance || HdmiArcPortID == -1) - return; - if (HdmiArcPortID == 0 ) - physical_addr_arc_port = {0x01,0x00,0x00,0x00}; - if (HdmiArcPortID == 1 ) - physical_addr_arc_port = {0x02,0x00,0x00,0x00}; - if (HdmiArcPortID == 2 ) - physical_addr_arc_port = {0x03,0x00,0x00,0x00}; - - if( (HdmiCecSink::_instance->deviceList[0x5].m_physicalAddr.toString() == physical_addr_arc_port.toString()) || (HdmiCecSink::_instance->deviceList[0x5].m_physicalAddr.toString() == physical_addr_invalid.toString()) ) { - LOGINFO("Command: INITIATE_ARC InitiateArc success %s \n",HdmiCecSink::_instance->deviceList[0x5].m_physicalAddr.toString().c_str()); - HdmiCecSink::_instance->Process_InitiateArc(); - } else { - LOGINFO("Command: INITIATE_ARC InitiateArc ignore %s \n",HdmiCecSink::_instance->deviceList[0x5].m_physicalAddr.toString().c_str()); - } - } - void HdmiCecSinkProcessor::process (const TerminateArc &msg, const Header &header) - { - printHeader(header); - if((!(header.from.toInt() == 0x5)) || (header.to.toInt() == LogicalAddress::BROADCAST)){ - LOGINFO("Ignoring the message coming from addresses other than 0X5 or a braodcast message"); - return; - } - if(!HdmiCecSink::_instance) - return; - HdmiCecSink::_instance->Process_TerminateArc(); - } - void HdmiCecSinkProcessor::process (const ReportShortAudioDescriptor &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: ReportShortAudioDescriptor %s : %d \n",GetOpName(msg.opCode()),numberofdescriptor); - HdmiCecSink::_instance->Process_ShortAudioDescriptor_msg(msg); - } - - void HdmiCecSinkProcessor::process (const SetSystemAudioMode &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: SetSystemAudioMode %s audio status %d audio status is %s \n",GetOpName(msg.opCode()),msg.status.toInt(),msg.status.toString().c_str()); - HdmiCecSink::_instance->Process_SetSystemAudioMode_msg(msg); - } - void HdmiCecSinkProcessor::process (const ReportAudioStatus &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n",GetOpName(msg.opCode()),msg.status.getAudioMuteStatus(),msg.status.toString().c_str(),msg.status.getAudioVolume()); - if(header.to.toInt() == LogicalAddress::BROADCAST){ - LOGINFO("Ignore Broadcast messages, accepts only direct messages"); - return; - } - HdmiCecSink::_instance->Process_ReportAudioStatus_msg(msg); - } - void HdmiCecSinkProcessor::process (const GiveFeatures &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: GiveFeatures \n"); - try - { - if(cecVersion == 2.0) { - conn.sendToAsync(LogicalAddress(LogicalAddress::BROADCAST),MessageEncoder().encode(ReportFeatures(Version::V_2_0,allDevicetype,rcProfile,deviceFeatures))); - } - } - catch(...) - { - LOGWARN("Exception while sending ReportFeatures"); - } - } - void HdmiCecSinkProcessor::process (const RequestCurrentLatency &msg, const Header &header) - { - printHeader(header); - LOGINFO("Command: Request Current Latency :%s, physical address: %s",GetOpName(msg.opCode()),msg.physicaladdress.toString().c_str()); - - if(msg.physicaladdress.toString() == physical_addr.toString()) { - HdmiCecSink::_instance->setLatencyInfo(); - } - else { - LOGINFO("Physical Address does not match with TV's physical address"); - return; - } - } //=========================================== HdmiCecSink ========================================= HdmiCecSink::HdmiCecSink() @@ -693,7 +156,6 @@ namespace WPEFramework } const std::string HdmiCecSink::Initialize(PluginHost::IShell *service) { - InitializePowerManager(service); profileType = searchRdkProfile(); if (profileType == STB || profileType == NOT_FOUND) @@ -702,118 +164,40 @@ namespace WPEFramework return (std::string("Not supported")); } - HdmiCecSink::_instance = this; - smConnection=NULL; - cecEnableStatus = false; - HdmiCecSink::_instance->m_numberOfDevices = 0; - m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; - m_currentActiveSource = -1; - m_isHdmiInConnected = false; - hdmiCecAudioDeviceConnected = false; - m_audioDevicePowerStatusRequested = false; - m_pollNextState = POLL_THREAD_STATE_NONE; - m_pollThreadState = POLL_THREAD_STATE_NONE; - m_video_latency = DEFAULT_VIDEO_LATENCY; - m_latency_flags = DEFAULT_LATENCY_FLAGS ; - m_audio_output_delay = DEFAULT_AUDIO_OUTPUT_DELAY; - - Register(HDMICECSINK_METHOD_SET_ENABLED, &HdmiCecSink::setEnabledWrapper, this); - Register(HDMICECSINK_METHOD_GET_ENABLED, &HdmiCecSink::getEnabledWrapper, this); - Register(HDMICECSINK_METHOD_SET_OSD_NAME, &HdmiCecSink::setOSDNameWrapper, this); - Register(HDMICECSINK_METHOD_GET_OSD_NAME, &HdmiCecSink::getOSDNameWrapper, this); - Register(HDMICECSINK_METHOD_SET_VENDOR_ID, &HdmiCecSink::setVendorIdWrapper, this); - Register(HDMICECSINK_METHOD_GET_VENDOR_ID, &HdmiCecSink::getVendorIdWrapper, this); - Register(HDMICECSINK_METHOD_PRINT_DEVICE_LIST, &HdmiCecSink::printDeviceListWrapper, this); - Register(HDMICECSINK_METHOD_SET_ACTIVE_PATH, &HdmiCecSink::setActivePathWrapper, this); - Register(HDMICECSINK_METHOD_SET_ROUTING_CHANGE, &HdmiCecSink::setRoutingChangeWrapper, this); - Register(HDMICECSINK_METHOD_GET_DEVICE_LIST, &HdmiCecSink::getDeviceListWrapper, this); - Register(HDMICECSINK_METHOD_GET_ACTIVE_SOURCE, &HdmiCecSink::getActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_SET_ACTIVE_SOURCE, &HdmiCecSink::setActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_GET_ACTIVE_ROUTE, &HdmiCecSink::getActiveRouteWrapper, this); - Register(HDMICECSINK_METHOD_REQUEST_ACTIVE_SOURCE, &HdmiCecSink::requestActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_SETUP_ARC, &HdmiCecSink::setArcEnableDisableWrapper, this); - Register(HDMICECSINK_METHOD_SET_MENU_LANGUAGE, &HdmiCecSink::setMenuLanguageWrapper, this); - Register(HDMICECSINK_METHOD_REQUEST_SHORT_AUDIO_DESCRIPTOR, &HdmiCecSink::requestShortAudioDescriptorWrapper, this); - Register(HDMICECSINK_METHOD_SEND_STANDBY_MESSAGE, &HdmiCecSink::sendStandbyMessageWrapper, this); - Register(HDMICECSINK_METHOD_SEND_AUDIO_DEVICE_POWER_ON, &HdmiCecSink::sendAudioDevicePowerOnMsgWrapper, this); - Register(HDMICECSINK_METHOD_SEND_KEY_PRESS,&HdmiCecSink::sendRemoteKeyPressWrapper,this); - Register(HDMICECSINK_METHOD_SEND_USER_CONTROL_PRESSED,&HdmiCecSink::sendUserControlPressedWrapper,this); - Register(HDMICECSINK_METHOD_SEND_USER_CONTROL_RELEASED,&HdmiCecSink::sendUserControlReleasedWrapper,this); - Register(HDMICECSINK_METHOD_SEND_GIVE_AUDIO_STATUS,&HdmiCecSink::sendGiveAudioStatusWrapper,this); - Register(HDMICECSINK_METHOD_GET_AUDIO_DEVICE_CONNECTED_STATUS,&HdmiCecSink::getAudioDeviceConnectedStatusWrapper,this); - Register(HDMICECSINK_METHOD_REQUEST_AUDIO_DEVICE_POWER_STATUS,&HdmiCecSink::requestAudioDevicePowerStatusWrapper,this); - Register(HDMICECSINK_METHOD_SET_LATENCY_INFO, &HdmiCecSink::setLatencyInfoWrapper, this); - logicalAddressDeviceType = "None"; - logicalAddress = 0xFF; - m_sendKeyEventThreadExit = false; - m_sendKeyEventThread = std::thread(threadSendKeyEvent); + string msg = ""; - m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; - m_semSignaltoArcRoutingThread.acquire(); - m_arcRoutingThread = std::thread(threadArcRouting); + ASSERT(nullptr != service); + ASSERT(nullptr == _service); + ASSERT(nullptr == _hdmiCecSink); + ASSERT(0 == _connectionId); - m_arcStartStopTimer.connect( std::bind( &HdmiCecSink::arcStartStopTimerFunction, this ) ); - m_arcStartStopTimer.setSingleShot(true); - // load persistence setting - loadSettings(); + _service = service; + _service->AddRef(); + _service->Register(&_notification); + _hdmiCecSink = _service->Root(_connectionId, 5000, _T("HdmiCecSinkImplementation")); - int err; - dsHdmiInGetNumberOfInputsParam_t hdmiInput; - InitializeIARM(); - // get power state: - uint32_t res = Core::ERROR_GENERAL; - PowerState pwrStateCur = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; - PowerState pwrStatePrev = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; - - ASSERT (_powerManagerPlugin); - if (_powerManagerPlugin) { - res = _powerManagerPlugin->GetPowerState(pwrStateCur, pwrStatePrev); - if (Core::ERROR_NONE == res) { - powerState = (pwrStateCur == WPEFramework::Exchange::IPowerManager::POWER_STATE_ON) ? DEVICE_POWER_STATE_ON : DEVICE_POWER_STATE_OFF; - LOGINFO("Current state is PowerManagerPlugin: (%d) powerState :%d \n", pwrStateCur, powerState); - } + if(nullptr != _hdmiCecSink) + { + _hdmiCecSink->Configure(service); + _hdmiCecSink->Register(&_notification); + Exchange::JHdmiCecSink::Register(*this, _hdmiCecSink); + LOGINFO("HdmiCecSink plugin is available. Successfully activated HdmiCecSink Plugin"); + } + else + { + msg = "HdmiCecSink plugin is not available"; + LOGINFO("HdmiCecSink plugin is not available. Failed to activate HdmiCecSink Plugin"); } - err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_API_dsHdmiInGetNumberOfInputs, - (void *)&hdmiInput, - sizeof(hdmiInput)); - - if (err == IARM_RESULT_SUCCESS && hdmiInput.result == dsERR_NONE) - { - LOGINFO("Number of Inputs [%d] \n", hdmiInput.numHdmiInputs ); - m_numofHdmiInput = hdmiInput.numHdmiInputs; - }else{ - LOGINFO("Not able to get Numebr of inputs so defaulting to 3 \n"); - m_numofHdmiInput = 3; - } - - LOGINFO("initalize inputs \n"); - - for (int i = 0; i < m_numofHdmiInput; i++){ - HdmiPortMap hdmiPort((uint8_t)i); - LOGINFO(" Add to vector [%d] \n", i); - hdmiInputs.push_back(hdmiPort); - } - - LOGINFO("Check the HDMI State \n"); - - CheckHdmiInState(); - if (cecSettingEnabled) + if (0 != msg.length()) { - try - { - CECEnable(); - } - catch(...) - { - LOGWARN("Exception while enabling CEC settings .\r\n"); - } + Deinitialize(service); } - getCecVersion(); - getHdmiArcPortID(); - return (std::string()); + + // On success return empty, to indicate there is no error text. + return msg; + } @@ -834,2639 +218,50 @@ namespace WPEFramework } CECDisable(); - m_currentArcRoutingState = ARC_STATE_ARC_EXIT; - - m_semSignaltoArcRoutingThread.release(); - - try - { - if (m_arcRoutingThread.joinable()) - m_arcRoutingThread.join(); - } - catch(const std::system_error& e) - { - LOGERR("system_error exception in thread join %s", e.what()); - } - catch(const std::exception& e) - { - LOGERR("exception in thread join %s", e.what()); - } - - { - m_sendKeyEventThreadExit = true; - std::unique_lock lk(m_sendKeyEventMutex); - m_sendKeyEventThreadRun = true; - m_sendKeyCV.notify_one(); - } - - try - { - if (m_sendKeyEventThread.joinable()) - m_sendKeyEventThread.join(); - } - catch(const std::system_error& e) - { - LOGERR("system_error exception in thread join %s", e.what()); - } - catch(const std::exception& e) - { - LOGERR("exception in thread join %s", e.what()); - } - - HdmiCecSink::_instance = nullptr; - DeinitializeIARM(); - LOGWARN(" HdmiCecSink Deinitialize() Done"); - } - - const void HdmiCecSink::InitializeIARM() - { - if (Utils::IARM::init()) - { - IARM_Result_t res; - IARM_CHECK( IARM_Bus_RegisterEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG, dsHdmiEventHandler) ); - } - } - - void HdmiCecSink::DeinitializeIARM() - { - if (Utils::IARM::isConnected()) - { - IARM_Result_t res; - IARM_CHECK( IARM_Bus_RemoveEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG, dsHdmiEventHandler) ); - } - } - - void HdmiCecSink::InitializePowerManager(PluginHost::IShell *service) - { - _powerManagerPlugin = PowerManagerInterfaceBuilder(_T("org.rdk.PowerManager")) - .withIShell(service) - .withRetryIntervalMS(200) - .withRetryCount(25) - .createInterface(); - registerEventHandlers(); - } - void HdmiCecSink::registerEventHandlers() - { - ASSERT (_powerManagerPlugin); - - if(!_registeredEventHandlers && _powerManagerPlugin) { - _registeredEventHandlers = true; - _powerManagerPlugin->Register(_pwrMgrNotification.baseInterface()); - } - } - - void HdmiCecSink::dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) - { - if(!HdmiCecSink::_instance) - return; - - if (IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG == eventId) - { - IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; - bool isHdmiConnected = eventData->data.hdmi_in_connect.isPortConnected; - dsHdmiInPort_t portId = eventData->data.hdmi_in_connect.port; - LOGINFO("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG event port: %d data:%d \r\n",portId, isHdmiConnected); - HdmiCecSink::_instance->onHdmiHotPlug(portId,isHdmiConnected); - } - } - - void HdmiCecSink::onPowerModeChanged(const PowerState ¤tState, const PowerState &newState) - { - if(!HdmiCecSink::_instance) - return; - - LOGINFO("Event IARM_BUS_PWRMGR_EVENT_MODECHANGED: State Changed %d -- > %d\r", - currentState, newState); - LOGWARN(" m_logicalAddressAllocated 0x%x CEC enable status %d \n",_instance->m_logicalAddressAllocated,_instance->cecEnableStatus); - if(newState == WPEFramework::Exchange::IPowerManager::POWER_STATE_ON) - { - powerState = DEVICE_POWER_STATE_ON; - } - else - { - powerState = DEVICE_POWER_STATE_OFF; - if((_instance->m_currentArcRoutingState == ARC_STATE_REQUEST_ARC_INITIATION) || (_instance->m_currentArcRoutingState == ARC_STATE_ARC_INITIATED)) - { - LOGINFO("%s: Stop ARC \n",__FUNCTION__); - _instance->stopArc(); - } - - } - if (_instance->cecEnableStatus) - { - if ( _instance->m_logicalAddressAllocated != LogicalAddress::UNREGISTERED ) - { - _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus = PowerStatus(powerState); - if ( powerState != DEVICE_POWER_STATE_ON ) - { - /* reset the current active source when TV on going to standby */ - HdmiCecSink::_instance->m_currentActiveSource = -1; - } - /* Initiate a ping straight away */ - HdmiCecSink::_instance->m_pollNextState = POLL_THREAD_STATE_PING; - HdmiCecSink::_instance->m_ThreadExitCV.notify_one(); - } - } - else - { - LOGWARN("CEC not Enabled\n"); - } - } - - - void HdmiCecSink::sendStandbyMessage() - { - if(!HdmiCecSink::_instance) - return; - if(!(HdmiCecSink::_instance->smConnection)) - return; - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ - LOGERR("Logical Address NOT Allocated Or its not valid"); - return; - } - - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(Standby()), 1000); - } - - void HdmiCecSink::onHdmiHotPlug(int portId , int connectStatus) - { - LOGINFO("onHdmiHotPlug Status : %d ", connectStatus); - if(!connectStatus) - { - LOGINFO(" removeDevice port: %d Logical address :%d \r\n",portId,hdmiInputs[portId].m_logicalAddr.toInt() ); - _instance->removeDevice(hdmiInputs[portId].m_logicalAddr.toInt()); - } - CheckHdmiInState(); - - if(cecEnableStatus) { - LOGINFO("cecEnableStatus : %d Trigger CEC Ping !!! \n", cecEnableStatus); - m_pollNextState = POLL_THREAD_STATE_PING; - m_ThreadExitCV.notify_one(); - } - if( HdmiArcPortID >= 0 ) { - updateArcState(); - } - return; - } - void HdmiCecSink::updateArcState() - { - if ( m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED ) + if(nullptr != _hdmiCecSink) { - if (!(hdmiInputs[HdmiArcPortID].m_isConnected)) - { - std::lock_guard lock(_instance->m_arcRoutingStateMutex); - m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; - } - else + _hdmiCecSink->Unregister(&_notification); + Exchange::JHdmiCecSink::Unregister(*this); + _hdmiCecSink->Release(); + _hdmiCecSink = nullptr; + + RPC::IRemoteConnection* connection = _service->RemoteConnection(_connectionId); + if (connection != nullptr) + { + try{ + connection->Terminate(); + } + catch(const std::exception& e) { - LOGINFO("updateArcState :not updating ARC state current arc state %d ",m_currentArcRoutingState); + std::string errorMessage = "Failed to terminate connection: "; + errorMessage += e.what(); + LOGWARN("%s",errorMessage.c_str()); } - } - } - void HdmiCecSink::arcStartStopTimerFunction() - { - JsonObject params; - if (m_arcstarting) - { - LOGINFO("arcStartStopTimerFunction ARC start timer expired"); - LOGINFO("notify_device setting that Initiate ARC failed to get the ARC_STATE_ARC_INITIATED state\n"); - params["status"] = string("failure"); - sendNotify(eventString[HDMICECSINK_EVENT_ARC_INITIATION_EVENT], params); - } - else - { - LOGINFO("arcStartStopTimerFunction ARC stop timer expired"); - LOGINFO("notify_device setting that Terminate ARC failed to get the ARC_STATE_ARC_TERMINATED state\n"); - params["status"] = string("failure"); - sendNotify(eventString[HDMICECSINK_EVENT_ARC_TERMINATION_EVENT], params); - - - } - /* bring the state machine to the clean state for a new start */ - std::lock_guard lock(_instance->m_arcRoutingStateMutex); - m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; - } - void HdmiCecSink::Send_ShortAudioDescriptor_Event(JsonArray audiodescriptor) - { - JsonObject params; + connection->Release(); + } + } - LOGINFO("Notify the DS "); - params["ShortAudioDescriptor"]= JsonValue(audiodescriptor); - sendNotify(eventString[HDMICECSINK_EVENT_SHORT_AUDIODESCRIPTOR_EVENT], params); + _connectionId = 0; + _service->Release(); + _service = nullptr; + LOGWARN(" HdmiCecSink Deinitialize() Done"); } - void HdmiCecSink::Process_ShortAudioDescriptor_msg(const ReportShortAudioDescriptor &msg) - { - uint8_t numberofdescriptor = msg.numberofdescriptor; - uint32_t descriptor =0; - JsonArray audiodescriptor; - - if (numberofdescriptor) - { - for( uint8_t i=0; i < numberofdescriptor; i++) - { - descriptor = msg.shortAudioDescriptor[i].getAudiodescriptor(); - - LOGINFO("descriptor%d 0x%x\n",i,descriptor); - audiodescriptor.Add(descriptor); - - } - } - else - { - audiodescriptor.Add(descriptor); - } - HdmiCecSink::_instance->Send_ShortAudioDescriptor_Event(audiodescriptor); - } - - void HdmiCecSink::updateCurrentLatency(int videoLatency, bool lowLatencyMode,int audioOutputCompensated, int audioOutputDelay = 0) - { - uint8_t latencyFlags = 0; - latencyFlags = ((lowLatencyMode & 0x1) << 2) | (audioOutputCompensated & 0x3); - LOGINFO("Video Latency : %d , Low Latency Mode : %d ,Audio Output Compensated value : %d , Audio Output Delay : %d , Latency Flags: %d ", videoLatency, lowLatencyMode, audioOutputCompensated, audioOutputDelay, latencyFlags); - m_video_latency = (videoLatency/2) + 1; - m_latency_flags = latencyFlags; - m_audio_output_delay = (audioOutputDelay/2) + 1; - setLatencyInfo(); - } - - void HdmiCecSink::setLatencyInfo() + string HdmiCecSink::Information() const { - if(!HdmiCecSink::_instance) - return; - - if(!(_instance->smConnection)) - return; - - LOGINFO("Send Report Current Latency message \n"); - _instance->smConnection->sendTo(LogicalAddress::BROADCAST,MessageEncoder().encode(ReportCurrentLatency(physical_addr,m_video_latency,m_latency_flags,m_audio_output_delay))); - + return("This HdmiCecSink PLugin Facilitates the HDMI CEC Sink Control"); } - void HdmiCecSink::Process_SetSystemAudioMode_msg(const SetSystemAudioMode &msg) + void HdmiCecSink::Deactivated(RPC::IRemoteConnection* connection) { - JsonObject params; - if(!HdmiCecSink::_instance) - return; - - //DD: Check cecSettingEnabled to prevent race conditions which gives immediate UI setting status - //SetSystemAudioMode message may come from AVR/Soundbar while CEC disable is in-progress - if ( cecSettingEnabled != true ) - { - LOGINFO("Process SetSystemAudioMode from Audio device: Cec is disabled-> EnableCEC first"); - return; - } - - if ( (msg.status.toInt() == SYSTEM_AUDIO_MODE_OFF) && (m_currentArcRoutingState == ARC_STATE_ARC_INITIATED)) + if (connection->Id() == _connectionId) { - /* ie system audio mode off -> amplifier goign to standby but still ARC is in initiated state,stop ARC and - bring the ARC state machine to terminated state*/ - LOGINFO("system audio mode off message but arc is not in terminated state so stopping ARC"); - stopArc(); - + ASSERT(_service != nullptr); + Core::IWorkerPool::Instance().Submit(PluginHost::IShell::Job::Create(_service, PluginHost::IShell::DEACTIVATED, PluginHost::IShell::FAILURE)); } - - params["audioMode"] = msg.status.toString().c_str(); - if (msg.status.toInt() == SYSTEM_AUDIO_MODE_ON) { - LOGINFO("panel power state is %s", powerState ? "Off" : "On"); - if (powerState == DEVICE_POWER_STATE_ON ) { - LOGINFO("Notifying system audio mode ON event"); - sendNotify(eventString[HDMICECSINK_EVENT_SYSTEM_AUDIO_MODE], params); - } else { - LOGINFO("Not notifying system audio mode ON event"); - } - } else { - LOGINFO("Notifying system audio Mode OFF event"); - sendNotify(eventString[HDMICECSINK_EVENT_SYSTEM_AUDIO_MODE], params); - } - } - void HdmiCecSink::Process_ReportAudioStatus_msg(const ReportAudioStatus msg) - { - JsonObject params; - if(!HdmiCecSink::_instance) - return; - LOGINFO("Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n",GetOpName(msg.opCode()),msg.status.getAudioMuteStatus(),msg.status.toString().c_str(),msg.status.getAudioVolume()); - params["muteStatus"] = msg.status.getAudioMuteStatus(); - params["volumeLevel"] = msg.status.getAudioVolume(); - sendNotify(eventString[HDMICECSINK_EVENT_REPORT_AUDIO_STATUS], params); - - } - void HdmiCecSink::sendKeyPressEvent(const int logicalAddress, int keyCode) - { - if(!(_instance->smConnection)) - return; - LOGINFO(" sendKeyPressEvent logicalAddress 0x%x keycode 0x%x\n",logicalAddress,keyCode); - switch(keyCode) - { - case VOLUME_UP: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_VOLUME_UP)),100); - break; - case VOLUME_DOWN: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_VOLUME_DOWN)), 100); - break; - case MUTE: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_MUTE)), 100); - break; - case UP: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_UP)), 100); - break; - case DOWN: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_DOWN)), 100); - break; - case LEFT: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_LEFT)), 100); - break; - case RIGHT: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_RIGHT)), 100); - break; - case SELECT: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_SELECT)), 100); - break; - case HOME: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_HOME)), 100); - break; - case BACK: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_BACK)), 100); - break; - case NUMBER_0: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_0)), 100); - break; - case NUMBER_1: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_1)), 100); - break; - case NUMBER_2: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_2)), 100); - break; - case NUMBER_3: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_3)), 100); - break; - case NUMBER_4: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_4)), 100); - break; - case NUMBER_5: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_5)), 100); - break; - case NUMBER_6: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_6)), 100); - break; - case NUMBER_7: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_7)), 100); - break; - case NUMBER_8: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_8)), 100); - break; - case NUMBER_9: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_9)), 100); - break; - - } - } - - void HdmiCecSink::sendUserControlPressed(const int logicalAddress, int keyCode) - { - if(!(_instance->smConnection)) - return; - LOGINFO(" sendUserControlPressed logicalAddress 0x%x keycode 0x%x\n",logicalAddress,keyCode); - switch(keyCode) - { - case VOLUME_UP: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_VOLUME_UP)),100); - break; - case VOLUME_DOWN: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_VOLUME_DOWN)), 100); - break; - case MUTE: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_MUTE)), 100); - break; - case UP: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_UP)), 100); - break; - case DOWN: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_DOWN)), 100); - break; - case LEFT: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_LEFT)), 100); - break; - case RIGHT: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_RIGHT)), 100); - break; - case SELECT: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_SELECT)), 100); - break; - case HOME: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_HOME)), 100); - break; - case BACK: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_BACK)), 100); - break; - case NUMBER_0: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_0)), 100); - break; - case NUMBER_1: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_1)), 100); - break; - case NUMBER_2: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_2)), 100); - break; - case NUMBER_3: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_3)), 100); - break; - case NUMBER_4: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_4)), 100); - break; - case NUMBER_5: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_5)), 100); - break; - case NUMBER_6: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_6)), 100); - break; - case NUMBER_7: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_7)), 100); - break; - case NUMBER_8: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_8)), 100); - break; - case NUMBER_9: - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_9)), 100); - break; - - } - } - - void HdmiCecSink::sendKeyReleaseEvent(const int logicalAddress) - { - if(!(_instance->smConnection)) - return; - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlReleased()), 100); - - } - - void HdmiCecSink::sendUserControlReleased(const int logicalAddress) - { - if(!(_instance->smConnection)) - return; - LOGINFO(" User Control Released \n"); - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlReleased()), 100); - } - - void HdmiCecSink::sendDeviceUpdateInfo(const int logicalAddress) - { - JsonObject params; - params["logicalAddress"] = JsonValue(logicalAddress); - sendNotify(eventString[HDMICECSINK_EVENT_DEVICE_INFO_UPDATED], params); - } - void HdmiCecSink::systemAudioModeRequest() - { - if ( cecEnableStatus != true ) - { - LOGINFO("systemAudioModeRequest: Cec is disabled-> EnableCEC first"); - return; - } - - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - LOGINFO(" Send systemAudioModeRequest "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(SystemAudioModeRequest(physical_addr)), 1000); - - } - void HdmiCecSink::sendGiveAudioStatusMsg() - { - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - LOGINFO(" Send GiveAudioStatus "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(GiveAudioStatus()), 100); - } - void HdmiCecSink::reportAudioDevicePowerStatusInfo(const int logicalAddress, const int powerStatus) - { - JsonObject params; - params["powerStatus"] = JsonValue(powerStatus); - LOGINFO("Panle power state is %s", powerState ? "Off" : "On"); - if (powerStatus != AUDIO_DEVICE_POWERSTATE_OFF) { - if (powerState == DEVICE_POWER_STATE_ON ) { - LOGINFO("Notify DS!!! logicalAddress = %d , Audio device power status = %d \n", logicalAddress, powerStatus); - sendNotify(eventString[HDMICECSINK_EVENT_AUDIO_DEVICE_POWER_STATUS], params); - } else { - LOGINFO("Not notifying audio device power state to DS"); - } - } else { - LOGINFO("Notify DS!!! logicalAddress = %d , Audio device power status = %d \n", logicalAddress, powerStatus); - sendNotify(eventString[HDMICECSINK_EVENT_AUDIO_DEVICE_POWER_STATUS], params); - } - } - - void HdmiCecSink::SendStandbyMsgEvent(const int logicalAddress) - { - JsonObject params; - if(!HdmiCecSink::_instance) - return; - params["logicalAddress"] = JsonValue(logicalAddress); - sendNotify(eventString[HDMICECSINK_EVENT_STANDBY_MSG_EVENT], params); - } - uint32_t HdmiCecSink::setEnabledWrapper(const JsonObject& parameters, JsonObject& response) - { - LOGINFOMETHOD(); - - bool enabled = false; - - if (parameters.HasLabel("enabled")) - { - getBoolParameter("enabled", enabled); - } - else - { - returnResponse(false); - } - - setEnabled(enabled); - returnResponse(true); - } - - uint32_t HdmiCecSink::getEnabledWrapper(const JsonObject& parameters, JsonObject& response) - { - response["enabled"] = getEnabled(); - returnResponse(true); - } - - uint32_t HdmiCecSink::getAudioDeviceConnectedStatusWrapper(const JsonObject& parameters, JsonObject& response) - { - response["connected"] = getAudioDeviceConnectedStatus(); - returnResponse(true); - } - - uint32_t HdmiCecSink::requestAudioDevicePowerStatusWrapper(const JsonObject& parameters, JsonObject& response) - { - requestAudioDevicePowerStatus(); - returnResponse(true); - } - - uint32_t HdmiCecSink::getActiveSourceWrapper(const JsonObject& parameters, JsonObject& response) - { - char routeString[1024] = {'\0'}; - int length = 0; - std::stringstream temp; - - if ( HdmiCecSink::_instance->m_currentActiveSource != -1 ) - { - int n = HdmiCecSink::_instance->m_currentActiveSource; - response["available"] = true; - response["logicalAddress"] = HdmiCecSink::_instance->deviceList[n].m_logicalAddress.toInt(); - response["physicalAddress"] = HdmiCecSink::_instance->deviceList[n].m_physicalAddr.toString().c_str(); - response["deviceType"] = HdmiCecSink::_instance->deviceList[n].m_deviceType.toString().c_str(); - response["cecVersion"] = HdmiCecSink::_instance->deviceList[n].m_cecVersion.toString().c_str(); - response["osdName"] = HdmiCecSink::_instance->deviceList[n].m_osdName.toString().c_str(); - response["vendorID"] = HdmiCecSink::_instance->deviceList[n].m_vendorID.toString().c_str(); - response["powerStatus"] = HdmiCecSink::_instance->deviceList[n].m_powerStatus.toString().c_str(); - - if ( HdmiCecSink::_instance->deviceList[n].m_physicalAddr.getByteValue(0) != 0 ) - { - snprintf(&routeString[length], sizeof(routeString) - length, "%s%d", "HDMI",(HdmiCecSink::_instance->deviceList[n].m_physicalAddr.getByteValue(0) - 1)); - } - else if ( HdmiCecSink::_instance->deviceList[n].m_physicalAddr.getByteValue(0) == 0 ) - { - snprintf(&routeString[length], sizeof(routeString) - length, "%s", "TV"); - } - - temp << (char *)routeString; - response["port"] = temp.str(); - - } - else - { - response["available"] = false; - } - - returnResponse(true); - } - - uint32_t HdmiCecSink::getDeviceListWrapper(const JsonObject& parameters, JsonObject& response) - { - LOGINFOMETHOD(); - - response["numberofdevices"] = HdmiCecSink::_instance->m_numberOfDevices; - LOGINFO("getDeviceListWrapper m_numberOfDevices :%d \n", HdmiCecSink::_instance->m_numberOfDevices); - JsonArray deviceList; - - for (int n = 0; n <= LogicalAddress::UNREGISTERED; n++) - { - - if ( n != HdmiCecSink::_instance->m_logicalAddressAllocated && - HdmiCecSink::_instance->deviceList[n].m_isDevicePresent ) - { - JsonObject device; - - device["logicalAddress"] = HdmiCecSink::_instance->deviceList[n].m_logicalAddress.toInt(); - device["physicalAddress"] = HdmiCecSink::_instance->deviceList[n].m_physicalAddr.toString().c_str(); - device["deviceType"] = HdmiCecSink::_instance->deviceList[n].m_deviceType.toString().c_str(); - device["cecVersion"] = HdmiCecSink::_instance->deviceList[n].m_cecVersion.toString().c_str(); - device["osdName"] = HdmiCecSink::_instance->deviceList[n].m_osdName.toString().c_str(); - device["vendorID"] = HdmiCecSink::_instance->deviceList[n].m_vendorID.toString().c_str(); - device["powerStatus"] = HdmiCecSink::_instance->deviceList[n].m_powerStatus.toString().c_str(); - int hdmiPortNumber = -1; - LOGINFO("getDeviceListWrapper m_numofHdmiInput:%d looking for Logical Address :%d \n", m_numofHdmiInput, HdmiCecSink::_instance->deviceList[n].m_logicalAddress.toInt()); - for (int i=0; i < m_numofHdmiInput; i++) - { - LOGINFO("getDeviceListWrapper connected : %d, portid:%d LA: %d \n", hdmiInputs[i].m_isConnected, hdmiInputs[i].m_portID, hdmiInputs[i].m_logicalAddr.toInt()); - if(hdmiInputs[i].m_isConnected && hdmiInputs[i].m_logicalAddr.toInt() == HdmiCecSink::_instance->deviceList[n].m_logicalAddress.toInt()) - { - hdmiPortNumber = hdmiInputs[i].m_portID; - LOGINFO("got portid :%d break \n", hdmiPortNumber); - break; - } - } - device["portNumber"] = hdmiPortNumber; - deviceList.Add(device); - } - } - - response["deviceList"] = deviceList; - - returnResponse(true); - } - - - uint32_t HdmiCecSink::setOSDNameWrapper(const JsonObject& parameters, JsonObject& response) - { - LOGINFOMETHOD(); - - if (parameters.HasLabel("name")) - { - std::string osd = parameters["name"].String(); - LOGINFO("setOSDNameWrapper osdName: %s",osd.c_str()); - osdName = osd.c_str(); - Utils::persistJsonSettings (CEC_SETTING_ENABLED_FILE, CEC_SETTING_OSD_NAME, JsonValue(osd.c_str())); - } - else - { - returnResponse(false); - } - returnResponse(true); - } - - uint32_t HdmiCecSink::getOSDNameWrapper(const JsonObject& parameters, JsonObject& response) - { - response["name"] = osdName.toString(); - LOGINFO("getOSDNameWrapper osdName : %s \n",osdName.toString().c_str()); - returnResponse(true); - } - - uint32_t HdmiCecSink::printDeviceListWrapper(const JsonObject& parameters, JsonObject& response) - { - printDeviceList(); - response["printed"] = true; - returnResponse(true); - } - - uint32_t HdmiCecSink::setActiveSourceWrapper(const JsonObject& parameters, JsonObject& response) - { - setActiveSource(false); - returnResponse(true); - } - - uint32_t HdmiCecSink::setActivePathWrapper(const JsonObject& parameters, JsonObject& response) - { - if (parameters.HasLabel("activePath")) - { - std::string id = parameters["activePath"].String(); - PhysicalAddress phy_addr = PhysicalAddress(id); - - LOGINFO("Addr = %s, length = %zu", id.c_str(), id.length()); - - setStreamPath(phy_addr); - returnResponse(true); - } - else - { - returnResponse(false); - } - } - - uint32_t HdmiCecSink::getActiveRouteWrapper(const JsonObject& parameters, JsonObject& response) - { - std::vector route; - char routeString[1024] = {'\0'}; - int length = 0; - JsonArray pathList; - std::stringstream temp; - - if (HdmiCecSink::_instance->m_currentActiveSource != -1 && - HdmiCecSink::_instance->m_currentActiveSource != HdmiCecSink::_instance->m_logicalAddressAllocated ) - { - HdmiCecSink::_instance->getActiveRoute(LogicalAddress(HdmiCecSink::_instance->m_currentActiveSource), route); - - if (route.size()) - { - response["available"] = true; - response["length"] = route.size(); - - for (unsigned int i=0; i < route.size(); i++) - { - if ( route[i] != LogicalAddress::UNREGISTERED ) - { - JsonObject device; - - device["logicalAddress"] = HdmiCecSink::_instance->deviceList[route[i]].m_logicalAddress.toInt(); - device["physicalAddress"] = HdmiCecSink::_instance->deviceList[route[i]].m_physicalAddr.toString().c_str(); - device["deviceType"] = HdmiCecSink::_instance->deviceList[route[i]].m_deviceType.toString().c_str(); - device["osdName"] = HdmiCecSink::_instance->deviceList[route[i]].m_osdName.toString().c_str(); - device["vendorID"] = HdmiCecSink::_instance->deviceList[route[i]].m_vendorID.toString().c_str(); - - pathList.Add(device); - - snprintf(&routeString[length], sizeof(routeString) - length, "%s", _instance->deviceList[route[i]].m_logicalAddress.toString().c_str()); - length += _instance->deviceList[route[i]].m_logicalAddress.toString().length(); - snprintf(&routeString[length], sizeof(routeString) - length, "(%s", _instance->deviceList[route[i]].m_osdName.toString().c_str()); - length += _instance->deviceList[route[i]].m_osdName.toString().length(); - snprintf(&routeString[length], sizeof(routeString) - length, "%s", ")-->"); - length += strlen(")-->"); - if( i + 1 == route.size() ) - { - snprintf(&routeString[length], sizeof(routeString) - length, "%s%d", "HDMI",(HdmiCecSink::_instance->deviceList[route[i]].m_physicalAddr.getByteValue(0) - 1)); - } - } - } - - response["pathList"] = pathList; - temp << (char *)routeString; - response["ActiveRoute"] = temp.str(); - LOGINFO("ActiveRoute = [%s]", routeString); - } - - } - else if ( HdmiCecSink::_instance->m_currentActiveSource == HdmiCecSink::_instance->m_logicalAddressAllocated ) - { - response["available"] = true; - response["ActiveRoute"] = "TV"; - } - else - { - response["available"] = false; - } - - returnResponse(true); - } - - uint32_t HdmiCecSink::requestActiveSourceWrapper(const JsonObject& parameters, JsonObject& response) - { - requestActiveSource(); - returnResponse(true); - } - - uint32_t HdmiCecSink::setRoutingChangeWrapper(const JsonObject& parameters, JsonObject& response) - { - std::string oldPortID; - std::string newPortID; - - returnIfParamNotFound(parameters, "oldPort"); - returnIfParamNotFound(parameters, "newPort"); - - oldPortID = parameters["oldPort"].String(); - newPortID = parameters["newPort"].String(); - - - if ((oldPortID.find("HDMI",0) != std::string::npos || - oldPortID.find("TV",0) != std::string::npos ) && - ( newPortID.find("HDMI", 0) != std::string::npos || - newPortID.find("TV", 0) != std::string::npos )) - { - setRoutingChange(oldPortID, newPortID); - returnResponse(true); - } - else - { - returnResponse(false); - } - } - - - uint32_t HdmiCecSink::setMenuLanguageWrapper(const JsonObject& parameters, JsonObject& response) - { - std::string lang; - - returnIfParamNotFound(parameters, "language"); - - lang = parameters["language"].String(); - - setCurrentLanguage(Language(lang.data())); - sendMenuLanguage(); - returnResponse(true); - } - - - uint32_t HdmiCecSink::setVendorIdWrapper(const JsonObject& parameters, JsonObject& response) - { - LOGINFOMETHOD(); - - if (parameters.HasLabel("vendorid")) - { - std::string id = parameters["vendorid"].String(); - unsigned int vendorID = 0x00; - try - { - vendorID = stoi(id,NULL,16); - } - catch (...) - { - LOGWARN("Exception in setVendorIdWrapper set default value\n"); - vendorID = 0x0019FB; - } - appVendorId = {(uint8_t)(vendorID >> 16 & 0xff),(uint8_t)(vendorID>> 8 & 0xff),(uint8_t) (vendorID & 0xff)}; - LOGINFO("appVendorId : %s vendorID :%x \n",appVendorId.toString().c_str(), vendorID ); - - Utils::persistJsonSettings (CEC_SETTING_ENABLED_FILE, CEC_SETTING_VENDOR_ID, JsonValue(vendorID)); - } - else - { - returnResponse(false); - } - returnResponse(true); - } - uint32_t HdmiCecSink::setArcEnableDisableWrapper(const JsonObject& parameters, JsonObject& response) - { - - bool enabled = false; - - if (parameters.HasLabel("enabled")) - { - getBoolParameter("enabled", enabled); - } - else - { - returnResponse(false); - } - if(enabled) - { - startArc(); - } - else - { - stopArc(); - - } - - returnResponse(true); - } - uint32_t HdmiCecSink::getVendorIdWrapper(const JsonObject& parameters, JsonObject& response) - { - LOGINFO("getVendorIdWrapper appVendorId : %s \n",appVendorId.toString().c_str()); - response["vendorid"] = appVendorId.toString() ; - returnResponse(true); - } - - uint32_t HdmiCecSink::requestShortAudioDescriptorWrapper(const JsonObject& parameters, JsonObject& response) - { - requestShortaudioDescriptor(); - returnResponse(true); - } - uint32_t HdmiCecSink::sendStandbyMessageWrapper(const JsonObject& parameters, JsonObject& response) - { - sendStandbyMessage(); - returnResponse(true); - } - - uint32_t HdmiCecSink::sendAudioDevicePowerOnMsgWrapper(const JsonObject& parameters, JsonObject& response) - { - LOGINFO("%s invoked. \n",__FUNCTION__); - systemAudioModeRequest(); - returnResponse(true); - } - uint32_t HdmiCecSink::sendRemoteKeyPressWrapper(const JsonObject& parameters, JsonObject& response) - { - returnIfParamNotFound(parameters, "logicalAddress"); - returnIfParamNotFound(parameters, "keyCode"); - string logicalAddress = parameters["logicalAddress"].String(); - string keyCode = parameters["keyCode"].String(); - SendKeyInfo keyInfo; - keyInfo.logicalAddr = stoi(logicalAddress); - keyInfo.keyCode = stoi(keyCode); - keyInfo.UserControl = "sendKeyPressEvent"; - std::unique_lock lk(m_sendKeyEventMutex); - m_SendKeyQueue.push(keyInfo); - m_sendKeyEventThreadRun = true; - m_sendKeyCV.notify_one(); - LOGINFO("Post send key press event to queue size:%zu \n",m_SendKeyQueue.size()); - returnResponse(true); - } - - uint32_t HdmiCecSink::sendUserControlPressedWrapper(const JsonObject& parameters, JsonObject& response) - { - returnIfParamNotFound(parameters, "logicalAddress"); - returnIfParamNotFound(parameters, "keyCode"); - string logicalAddress = parameters["logicalAddress"].String(); - string keyCode = parameters["keyCode"].String(); - SendKeyInfo keyInfo; - keyInfo.logicalAddr = stoi(logicalAddress); - keyInfo.keyCode = stoi(keyCode); - keyInfo.UserControl = "sendUserControlPressed"; - std::unique_lock lk(m_sendKeyEventMutex); - m_SendKeyQueue.push(keyInfo); - m_sendKeyEventThreadRun = true; - m_sendKeyCV.notify_one(); - LOGINFO("User control pressed, queue size:%zu \n",m_SendKeyQueue.size()); - returnResponse(true); - } - - uint32_t HdmiCecSink::sendUserControlReleasedWrapper(const JsonObject& parameters, JsonObject& response) - { - returnIfParamNotFound(parameters, "logicalAddress"); - string logicalAddress = parameters["logicalAddress"].String(); - SendKeyInfo keyInfo; - keyInfo.logicalAddr = stoi(logicalAddress); - keyInfo.keyCode = 0; - keyInfo.UserControl = "sendUserControlReleased"; - std::unique_lock lk(m_sendKeyEventMutex); - m_SendKeyQueue.push(keyInfo); - m_sendKeyEventThreadRun = true; - m_sendKeyCV.notify_one(); - LOGINFO("User Control Released, queue size:%zu \n",m_SendKeyQueue.size()); - returnResponse(true); - } - - uint32_t HdmiCecSink::sendGiveAudioStatusWrapper(const JsonObject& parameters, JsonObject& response) - { - sendGiveAudioStatusMsg(); - returnResponse(true); - } - uint32_t HdmiCecSink::setLatencyInfoWrapper(const JsonObject& parameters, JsonObject& response) - { - int video_latency,audio_output_compensated,audio_output_delay; - bool low_latency_mode; - - returnIfParamNotFound(parameters, "videoLatency"); - returnIfParamNotFound(parameters, "lowLatencyMode"); - returnIfParamNotFound(parameters, "audioOutputCompensated"); - returnIfParamNotFound(parameters, "audioOutputDelay"); - video_latency = stoi(parameters["videoLatency"].String()); - low_latency_mode = stoi(parameters["lowLatencyMode"].String()); - audio_output_compensated = stoi(parameters["audioOutputCompensated"].String()); - audio_output_delay = stoi(parameters["audioOutputDelay"].String()); - - updateCurrentLatency(video_latency, low_latency_mode,audio_output_compensated, audio_output_delay); - returnResponse(true); - } - bool HdmiCecSink::loadSettings() - { - Core::File file; - file = CEC_SETTING_ENABLED_FILE; - - if( file.Open()) - { - JsonObject parameters; - parameters.IElement::FromFile(file); - bool isConfigAdded = false; - - if( parameters.HasLabel(CEC_SETTING_ENABLED)) - { - getBoolParameter(CEC_SETTING_ENABLED, cecSettingEnabled); - LOGINFO("CEC_SETTING_ENABLED present value:%d",cecSettingEnabled); - } - else - { - parameters[CEC_SETTING_ENABLED] = true; - cecSettingEnabled = true; - isConfigAdded = true; - LOGINFO("CEC_SETTING_ENABLED not present set dafult true:\n "); - } - - if( parameters.HasLabel(CEC_SETTING_OTP_ENABLED)) - { - getBoolParameter(CEC_SETTING_OTP_ENABLED, cecOTPSettingEnabled); - LOGINFO("CEC_SETTING_OTP_ENABLED present value :%d",cecOTPSettingEnabled); - } - else - { - parameters[CEC_SETTING_OTP_ENABLED] = true; - cecOTPSettingEnabled = true; - isConfigAdded = true; - LOGINFO("CEC_SETTING_OTP_ENABLED not present set dafult true:\n "); - } - if( parameters.HasLabel(CEC_SETTING_OSD_NAME)) - { - std::string osd_name; - getStringParameter(CEC_SETTING_OSD_NAME, osd_name); - osdName = osd_name.c_str(); - LOGINFO("CEC_SETTING_OSD_NAME present osd_name :%s",osdName.toString().c_str()); - } - else - { - parameters[CEC_SETTING_OSD_NAME] = osdName.toString(); - LOGINFO("CEC_SETTING_OSD_NMAE not present set dafult value :%s\n ",osdName.toString().c_str()); - isConfigAdded = true; - } - unsigned int vendorId = (defaultVendorId.at(0) <<16) | ( defaultVendorId.at(1) << 8 ) | defaultVendorId.at(2); - if( parameters.HasLabel(CEC_SETTING_VENDOR_ID)) - { - getNumberParameter(CEC_SETTING_VENDOR_ID, vendorId); - LOGINFO("CEC_SETTING_VENDOR_ID present :%x ",vendorId); - } - else - { - LOGINFO("CEC_SETTING_VENDOR_ID not present set dafult value :%x \n ",vendorId); - parameters[CEC_SETTING_VENDOR_ID] = vendorId; - isConfigAdded = true; - } - - appVendorId = {(uint8_t)(vendorId >> 16 & 0xff),(uint8_t)(vendorId >> 8 & 0xff),(uint8_t) (vendorId & 0xff)}; - LOGINFO("appVendorId : %s vendorId :%x \n",appVendorId.toString().c_str(), vendorId ); - - if(isConfigAdded) - { - LOGINFO("isConfigAdded true so update file:\n "); - file.Destroy(); - file.Create(); - parameters.IElement::ToFile(file); - - } - - file.Close(); - } - else - { - LOGINFO("CEC_SETTING_ENABLED_FILE file not present create with default settings "); - file.Open(false); - if (!file.IsOpen()) - file.Create(); - - JsonObject parameters; - unsigned int vendorId = (defaultVendorId.at(0) <<16) | ( defaultVendorId.at(1) << 8 ) | defaultVendorId.at(2); - parameters[CEC_SETTING_ENABLED] = true; - parameters[CEC_SETTING_OSD_NAME] = osdName.toString(); - parameters[CEC_SETTING_VENDOR_ID] = vendorId; - - cecSettingEnabled = true; - cecOTPSettingEnabled = true; - parameters.IElement::ToFile(file); - - file.Close(); - - } - - return cecSettingEnabled; - } - - void HdmiCecSink::setEnabled(bool enabled) - { - LOGINFO("Entered setEnabled: %d cecSettingEnabled :%d ",enabled, cecSettingEnabled); - - if (cecSettingEnabled != enabled) - { - Utils::persistJsonSettings (CEC_SETTING_ENABLED_FILE, CEC_SETTING_ENABLED, JsonValue(enabled)); - cecSettingEnabled = enabled; - } - if(true == enabled) - { - CECEnable(); - } - else - { - CECDisable(); - } - return; - } - - void HdmiCecSink::updateImageViewOn(const int logicalAddress) - { - JsonObject params; - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || - logicalAddress == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if (_instance->deviceList[logicalAddress].m_isDevicePresent && - _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) - - { - /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ - sendNotify(eventString[HDMICECSINK_EVENT_WAKEUP_FROM_STANDBY], params); - } - - sendNotify(eventString[HDMICECSINK_EVENT_IMAGE_VIEW_ON_MSG], params); - } - - void HdmiCecSink::updateTextViewOn(const int logicalAddress) - { - JsonObject params; - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || - logicalAddress == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if (_instance->deviceList[logicalAddress].m_isDevicePresent && - _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) - { - /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ - sendNotify(eventString[HDMICECSINK_EVENT_WAKEUP_FROM_STANDBY], params); - } - - sendNotify(eventString[HDMICECSINK_EVENT_TEXT_VIEW_ON_MSG], params); - } - - - void HdmiCecSink::updateDeviceChain(const LogicalAddress &logicalAddress, const PhysicalAddress &phy_addr) - { - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if (_instance->deviceList[logicalAddress.toInt()].m_isDevicePresent && - logicalAddress.toInt() != _instance->m_logicalAddressAllocated) - { - for (int i=0; i < m_numofHdmiInput; i++) - { - LOGINFO(" addr = %d, portID = %d", phy_addr.getByteValue(0), hdmiInputs[i].m_portID); - if (phy_addr.getByteValue(0) == (hdmiInputs[i].m_portID + 1)) { - hdmiInputs[i].addChild(logicalAddress, phy_addr); - } - } - } - } - - void HdmiCecSink::getActiveRoute(const LogicalAddress &logicalAddress, std::vector &route) - { - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || - logicalAddress.toInt() == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if (_instance->deviceList[logicalAddress.toInt()].m_isDevicePresent && - logicalAddress.toInt() != _instance->m_logicalAddressAllocated && - _instance->deviceList[logicalAddress.toInt()].m_isActiveSource ) - { - route.clear(); - for (int i=0; i < m_numofHdmiInput; i++) - { - LOGINFO("physicalAddress = [%d], portID = %d", _instance->deviceList[logicalAddress.toInt()].m_physicalAddr.getByteValue(0), hdmiInputs[i].m_portID); - if (_instance->deviceList[logicalAddress.toInt()].m_physicalAddr.getByteValue(0) == (hdmiInputs[i].m_portID + 1)) { - hdmiInputs[i].getRoute(_instance->deviceList[logicalAddress.toInt()].m_physicalAddr, route); - } - } - } - else { - LOGERR("Not in correct state to Find Route"); - } - } - - - void HdmiCecSink::CheckHdmiInState() - { - int err; - bool isAnyPortConnected = false; - - dsHdmiInGetStatusParam_t params; - err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_API_dsHdmiInGetStatus, - (void *)¶ms, - sizeof(params)); - - if(err == IARM_RESULT_SUCCESS && params.result == dsERR_NONE ) - { - for( int i = 0; i < m_numofHdmiInput; i++ ) - { - LOGINFO("Is HDMI In Port [%d] connected [%d] \n",i, params.status.isPortConnected[i]); - if ( params.status.isPortConnected[i] ) - { - isAnyPortConnected = true; - } - - LOGINFO("update Port Status [%d] \n", i); - hdmiInputs[i].update(params.status.isPortConnected[i]); - } - } - - if ( isAnyPortConnected ) { - m_isHdmiInConnected = true; - } else { - m_isHdmiInConnected = false; - } - } - - void HdmiCecSink::requestActiveSource() - { - if(!HdmiCecSink::_instance) - return; - - if(!(_instance->smConnection)) - return; - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - _instance->smConnection->sendTo(LogicalAddress::BROADCAST, - MessageEncoder().encode(RequestActiveSource()), 500); - } - - void HdmiCecSink::setActiveSource(bool isResponse) - { - if(!HdmiCecSink::_instance) - return; - - if(!(_instance->smConnection)) - return; - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if (isResponse && (_instance->m_currentActiveSource != _instance->m_logicalAddressAllocated) ) - { - LOGWARN("TV is not current Active Source"); - return; - } - - _instance->smConnection->sendTo(LogicalAddress::BROADCAST, - MessageEncoder().encode(ActiveSource(_instance->deviceList[_instance->m_logicalAddressAllocated].m_physicalAddr)), 500); - _instance->m_currentActiveSource = _instance->m_logicalAddressAllocated; - } - - void HdmiCecSink::setCurrentLanguage(const Language &lang) - { - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage = lang; - } - - void HdmiCecSink::sendMenuLanguage() - { - Language lang = ""; - if(!HdmiCecSink::_instance) - return; - - if(!(_instance->smConnection)) - return; - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - lang = _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage; - - _instance->smConnection->sendTo(LogicalAddress::BROADCAST, MessageEncoder().encode(SetMenuLanguage(lang)), 100); - } - - void HdmiCecSink::updateInActiveSource(const int logical_address, const InActiveSource &source ) - { - JsonObject params; - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if( logical_address != _instance->m_logicalAddressAllocated ) - { - _instance->deviceList[logical_address].m_isActiveSource = false; - - if ( _instance->m_currentActiveSource == logical_address ) - { - _instance->m_currentActiveSource = -1; - } - - params["logicalAddress"] = JsonValue(logical_address); - params["phsicalAddress"] = source.physicalAddress.toString().c_str(); - sendNotify(eventString[HDMICECSINK_EVENT_INACTIVE_SOURCE], params); - } - } - - void HdmiCecSink::updateActiveSource(const int logical_address, const ActiveSource &source ) - { - JsonObject params; - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if( logical_address != _instance->m_logicalAddressAllocated ) - { - if ( _instance->m_currentActiveSource != -1 ) - { - _instance->deviceList[_instance->m_currentActiveSource].m_isActiveSource = false; - } - - _instance->deviceList[logical_address].m_isActiveSource = true; - _instance->deviceList[logical_address].update(source.physicalAddress); - _instance->m_currentActiveSource = logical_address; - - if (_instance->deviceList[logical_address].m_isDevicePresent && - _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) - { - /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ - sendNotify(eventString[HDMICECSINK_EVENT_WAKEUP_FROM_STANDBY], params); - } - - params["logicalAddress"] = JsonValue(logical_address); - params["physicalAddress"] = _instance->deviceList[logical_address].m_physicalAddr.toString().c_str(); - sendNotify(eventString[HDMICECSINK_EVENT_ACTIVE_SOURCE_CHANGE], params); - } - } - - void HdmiCecSink::requestShortaudioDescriptor() - { - if ( cecEnableStatus != true ) - { - LOGINFO("requestShortaudioDescriptor: cec is disabled-> EnableCEC first"); - return; - } - - if(!HdmiCecSink::_instance) - return; - - if(!(_instance->smConnection)) - return; - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - LOGINFO(" Send requestShortAudioDescriptor Message "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestShortAudioDescriptor(formatid,audioFormatCode,numberofdescriptor)), 1000); - - } - - void HdmiCecSink::requestAudioDevicePowerStatus() - { - if ( cecEnableStatus != true ) - { - LOGWARN("cec is disabled-> EnableCEC first"); - return; - } - - if(!HdmiCecSink::_instance) - return; - - if(!(_instance->smConnection)) - return; - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - LOGINFO(" Send GiveDevicePowerStatus Message to Audio system in the network \n"); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM, MessageEncoder().encode(GiveDevicePowerStatus()), 500); - - m_audioDevicePowerStatusRequested = true; - } - - void HdmiCecSink::sendFeatureAbort(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason) - { - - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - LOGINFO(" Sending FeatureAbort to %s for opcode %s with reason %s ",logicalAddress.toString().c_str(),feature.toString().c_str(),reason.toString().c_str()); - _instance->smConnection->sendTo(logicalAddress, MessageEncoder().encode(FeatureAbort(feature,reason)), 500); - } - - void HdmiCecSink::reportFeatureAbortEvent(const LogicalAddress logicalAddress, const OpCode featureOpcode, const AbortReason abortReason) - { - LOGINFO(" Notifying the UI FeatureAbort from the %s for the opcode %s with the reason %s ",logicalAddress.toString().c_str(),featureOpcode.toString().c_str(),abortReason.toString().c_str()); - JsonObject params; - params["LogicalAddress"] = logicalAddress.toInt(); - params["opcode"] = featureOpcode.opCode(); - params["FeatureAbortReason"] = abortReason.toInt(); - sendNotify(eventString[HDMICECSINK_EVENT_FEATURE_ABORT_EVENT], params); - } - - void HdmiCecSink::pingDevices(std::vector &connected , std::vector &disconnected) - { - int i; - - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - for(i=0; i< LogicalAddress::UNREGISTERED; i++ ) { - if ( i != _instance->m_logicalAddressAllocated ) - { - //LOGWARN("PING for 0x%x \r\n",i); - try { - _instance->smConnection->ping(LogicalAddress(_instance->m_logicalAddressAllocated), LogicalAddress(i), Throw_e()); - } - catch(CECNoAckException &e) - { - if ( _instance->deviceList[i].m_isDevicePresent ) { - disconnected.push_back(i); - } - //LOGWARN("Ping device: 0x%x caught %s \r\n", i, e.what()); - usleep(50000); - continue; - } - catch(Exception &e) - { - LOGWARN("Ping device: 0x%x caught %s \r\n", i, e.what()); - usleep(50000); - continue; - } - - /* If we get ACK, then the device is present in the network*/ - if ( !_instance->deviceList[i].m_isDevicePresent ) - { - connected.push_back(i); - //LOGWARN("Ping success, added device: 0x%x \r\n", i); - } - usleep(50000); - } - } - } - - int HdmiCecSink::requestType( const int logicalAddress ) { - int requestType = CECDeviceParams::REQUEST_NONE; - - if ( !_instance->deviceList[logicalAddress].m_isPAUpdated || !_instance->deviceList[logicalAddress].m_isDeviceTypeUpdated ) { - requestType = CECDeviceParams::REQUEST_PHISICAL_ADDRESS; - }else if ( !_instance->deviceList[logicalAddress].m_isOSDNameUpdated ) { - requestType = CECDeviceParams::REQUEST_OSD_NAME; - }else if ( !_instance->deviceList[logicalAddress].m_isVersionUpdated ) { - requestType = CECDeviceParams::REQUEST_CEC_VERSION; - }else if ( !_instance->deviceList[logicalAddress].m_isVendorIDUpdated ) { - requestType = CECDeviceParams::REQUEST_DEVICE_VENDOR_ID; - }else if ( !_instance->deviceList[logicalAddress].m_isPowerStatusUpdated ) { - requestType = CECDeviceParams::REQUEST_POWER_STATUS; - } - - return requestType; - } - - void HdmiCecSink::printDeviceList() { - int i; - - if(!HdmiCecSink::_instance) - return; - - for(i=0; i< 16; i++) - { - if (HdmiCecSink::_instance->deviceList[i].m_isDevicePresent) { - LOGWARN("------ Device ID = %d--------", i); - HdmiCecSink::_instance->deviceList[i].printVariable(); - LOGWARN("-----------------------------"); - } - } - } - - void HdmiCecSink::setStreamPath( const PhysicalAddress &physical_addr) { - - if(!HdmiCecSink::_instance) - return; - - if(!(_instance->smConnection)) - return; - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ - LOGERR("Logical Address NOT Allocated Or its not valid"); - return; - } - - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(SetStreamPath(physical_addr)), 500); - } - - void HdmiCecSink::setRoutingChange(const std::string &from, const std::string &to) { - PhysicalAddress oldPhyAddr = {0xF,0xF,0xF,0xF}; - PhysicalAddress newPhyAddr = {0xF,0xF,0xF,0xF}; - int oldPortID = -1; - int newPortID = -1; - - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ - LOGERR("Logical Address NOT Allocated Or its not valid"); - return; - } - - if( from.find("TV",0) != std::string::npos ) - { - oldPhyAddr = _instance->deviceList[_instance->m_logicalAddressAllocated].m_physicalAddr; - _instance->m_currentActiveSource = -1; - } - else - { - oldPortID = stoi(from.substr(4,1),NULL,16); - if ( oldPortID < _instance->m_numofHdmiInput ) - { - oldPhyAddr = _instance->hdmiInputs[oldPortID].m_physicalAddr; - } - else - { - LOGERR("Invalid HDMI Old Port ID"); - return; - } - } - - if( to.find("TV",0) != std::string::npos ) - { - newPhyAddr = _instance->deviceList[_instance->m_logicalAddressAllocated].m_physicalAddr; - /*set active source as TV */ - _instance->m_currentActiveSource = _instance->m_logicalAddressAllocated; - } - else - { - newPortID = stoi(to.substr(4,1),NULL,16); - - if ( newPortID < _instance->m_numofHdmiInput ) - { - newPhyAddr = _instance->hdmiInputs[newPortID].m_physicalAddr; - } - else - { - LOGERR("Invalid HDMI New Port ID"); - return; - } - } - - if(!(_instance->smConnection)) - return; - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(RoutingChange(oldPhyAddr, newPhyAddr)), 500); - } - - void HdmiCecSink::addDevice(const int logicalAddress) { - JsonObject params; - - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if ( !HdmiCecSink::_instance->deviceList[logicalAddress].m_isDevicePresent ) - { - HdmiCecSink::_instance->deviceList[logicalAddress].m_isDevicePresent = true; - HdmiCecSink::_instance->deviceList[logicalAddress].m_logicalAddress = LogicalAddress(logicalAddress); - HdmiCecSink::_instance->m_numberOfDevices++; - HdmiCecSink::_instance->m_pollNextState = POLL_THREAD_STATE_INFO; - - if(logicalAddress == 0x5) - { - LOGINFO(" logicalAddress =%d , Audio device detected, Notify Device Settings", logicalAddress ); - params["status"] = string("success"); - params["audioDeviceConnected"] = string("true"); - hdmiCecAudioDeviceConnected = true; - sendNotify(eventString[HDMICECSINK_EVENT_AUDIO_DEVICE_CONNECTED_STATUS], params); - } - - sendNotify(eventString[HDMICECSINK_EVENT_DEVICE_ADDED], JsonObject()); - } - } - - void HdmiCecSink::removeDevice(const int logicalAddress) { - JsonObject params; - - if(!HdmiCecSink::_instance) - return; - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ - LOGERR("Logical Address NOT Allocated"); - return; - } - - if (_instance->deviceList[logicalAddress].m_isDevicePresent) - { - _instance->m_numberOfDevices--; - - for (int i=0; i < m_numofHdmiInput; i++) - { - if (_instance->deviceList[logicalAddress].m_physicalAddr.getByteValue(0) == (hdmiInputs[i].m_portID + 1)) { - hdmiInputs[i].removeChild(_instance->deviceList[logicalAddress].m_physicalAddr); - hdmiInputs[i].update(LogicalAddress(LogicalAddress::UNREGISTERED)); - } - } - - if(logicalAddress == 0x5) - { - LOGINFO(" logicalAddress =%d , Audio device removed, Notify Device Settings", logicalAddress ); - params["status"] = string("success"); - params["audioDeviceConnected"] = string("false"); - hdmiCecAudioDeviceConnected = false; - sendNotify(eventString[HDMICECSINK_EVENT_AUDIO_DEVICE_CONNECTED_STATUS], params); - } - - _instance->deviceList[logicalAddress].m_isRequestRetry = 0; - _instance->deviceList[logicalAddress].clear(); - sendNotify(eventString[HDMICECSINK_EVENT_DEVICE_REMOVED], JsonObject()); - } - } - - void HdmiCecSink::request(const int logicalAddress) { - int requestType; - - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || logicalAddress >= LogicalAddress::UNREGISTERED + TEST_ADD ){ - LOGERR("Logical Address NOT Allocated Or its not valid"); - return; - } - - requestType = _instance->requestType(logicalAddress); - _instance->deviceList[logicalAddress].m_isRequested = requestType; - - switch (requestType) - { - case CECDeviceParams::REQUEST_PHISICAL_ADDRESS : - { - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GivePhysicalAddress()), 200); - } - break; - - case CECDeviceParams::REQUEST_CEC_VERSION : - { - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GetCECVersion()), 100); - } - break; - - case CECDeviceParams::REQUEST_DEVICE_VENDOR_ID : - { - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GiveDeviceVendorID()), 100); - } - break; - - case CECDeviceParams::REQUEST_OSD_NAME : - { - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GiveOSDName()), 500); - } - break; - - case CECDeviceParams::REQUEST_POWER_STATUS : - { - _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GiveDevicePowerStatus()), 100); - } - break; - default: - { - _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; - } - break; - } - - _instance->deviceList[logicalAddress].m_requestTime = std::chrono::system_clock::now(); - LOGINFO("request type %d", _instance->deviceList[logicalAddress].m_isRequested); - } - - int HdmiCecSink::requestStatus(const int logicalAddress) { - std::chrono::duration elapsed; - bool isElapsed = false; - - if(!HdmiCecSink::_instance) - return -1; - - - if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || logicalAddress >= LogicalAddress::UNREGISTERED + TEST_ADD ) { - LOGERR("Logical Address NOT Allocated Or its not valid"); - return -1; - } - - switch ( _instance->deviceList[logicalAddress].m_isRequested ) { - case CECDeviceParams::REQUEST_PHISICAL_ADDRESS : - { - if( _instance->deviceList[logicalAddress].m_isPAUpdated && - _instance->deviceList[logicalAddress].m_isDeviceTypeUpdated ) - { - _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; - } - } - break; - - case CECDeviceParams::REQUEST_CEC_VERSION : - { - if( _instance->deviceList[logicalAddress].m_isVersionUpdated ) - { - _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; - } - } - break; - - case CECDeviceParams::REQUEST_DEVICE_VENDOR_ID : - { - if( _instance->deviceList[logicalAddress].m_isVendorIDUpdated ) - { - _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; - } - } - break; - - case CECDeviceParams::REQUEST_OSD_NAME : - { - if( _instance->deviceList[logicalAddress].m_isOSDNameUpdated ) - { - _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; - } - } - break; - - case CECDeviceParams::REQUEST_POWER_STATUS : - { - if( _instance->deviceList[logicalAddress].m_isPowerStatusUpdated ) - { - _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; - } - } - break; - default: - break; - } - - if ( _instance->deviceList[logicalAddress].m_isRequested != CECDeviceParams::REQUEST_NONE ) - { - elapsed = std::chrono::system_clock::now() - _instance->deviceList[logicalAddress].m_requestTime; - - if ( elapsed.count() > HDMICECSINK_REQUEST_MAX_WAIT_TIME_MS ) - { - LOGINFO("request elapsed "); - isElapsed = true; - } - } - - if (isElapsed) - { - /* For some request it should be retry, like report physical address etc for other we can have default values */ - switch( _instance->deviceList[logicalAddress].m_isRequested ) - { - case CECDeviceParams::REQUEST_PHISICAL_ADDRESS : - { - LOGINFO("Retry for REQUEST_PHISICAL_ADDRESS = %d", _instance->deviceList[logicalAddress].m_isRequestRetry); - /* Update with Invalid Physical Address */ - if ( _instance->deviceList[logicalAddress].m_isRequestRetry++ >= HDMICECSINK_REQUEST_MAX_RETRY ) - { - LOGINFO("Max retry for REQUEST_PHISICAL_ADDRESS = %d", _instance->deviceList[logicalAddress].m_isRequestRetry); - _instance->deviceList[logicalAddress].update(PhysicalAddress(0xF,0xF,0xF,0xF)); - _instance->deviceList[logicalAddress].update(DeviceType(DeviceType::RESERVED)); - _instance->deviceList[logicalAddress].m_isRequestRetry = 0; - } - } - break; - - case CECDeviceParams::REQUEST_CEC_VERSION : - { - /*Defaulting to 1.4*/ - _instance->deviceList[logicalAddress].update(Version(Version::V_1_4)); - } - break; - - case CECDeviceParams::REQUEST_DEVICE_VENDOR_ID : - { - _instance->deviceList[logicalAddress].update(VendorID(0,0,0)); - } - break; - - case CECDeviceParams::REQUEST_OSD_NAME : - { - if ( _instance->deviceList[logicalAddress].m_isRequestRetry++ >= HDMICECSINK_REQUEST_MAX_RETRY ) - { - LOGINFO("Max retry for REQUEST_OSD_NAME = %d", _instance->deviceList[logicalAddress].m_isRequestRetry); - _instance->deviceList[logicalAddress].update(OSDName("")); - _instance->deviceList[logicalAddress].m_isRequestRetry = 0; - } - } - break; - - case CECDeviceParams::REQUEST_POWER_STATUS : - { - _instance->deviceList[logicalAddress].update(PowerStatus(PowerStatus::POWER_STATUS_NOT_KNOWN)); - } - break; - default: - break; - } - - - _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; - } - - if( _instance->deviceList[logicalAddress].m_isRequested == CECDeviceParams::REQUEST_NONE) - { - LOGINFO("Request Done"); - return CECDeviceParams::REQUEST_DONE; - } - - //LOGINFO("Request NOT Done"); - return CECDeviceParams::REQUEST_NOT_DONE; - } - - void HdmiCecSink::threadRun() - { - std::vector connected; - std::vector disconnected; - int logicalAddressRequested = LogicalAddress::UNREGISTERED + TEST_ADD; - bool isExit = false; - - if(!HdmiCecSink::_instance) - return; - - if(!(_instance->smConnection)) - return; - LOGINFO("Entering ThreadRun: _instance->m_pollThreadExit %d isExit %d _instance->m_pollThreadState %d _instance->m_pollNextState %d",_instance->m_pollThreadExit,isExit,_instance->m_pollThreadState,_instance->m_pollNextState ); - _instance->m_sleepTime = HDMICECSINK_PING_INTERVAL_MS; - - while(1) - { - - if (_instance->m_pollThreadExit || isExit ){ - LOGWARN("Thread Exits _instance->m_pollThreadExit %d isExit %d _instance->m_pollThreadState %d _instance->m_pollNextState %d",_instance->m_pollThreadExit,isExit,_instance->m_pollThreadState,_instance->m_pollNextState ); - break; - } - - if ( _instance->m_pollNextState != POLL_THREAD_STATE_NONE ) - { - _instance->m_pollThreadState = _instance->m_pollNextState; - _instance->m_pollNextState = POLL_THREAD_STATE_NONE; - } - - switch (_instance->m_pollThreadState) { - - case POLL_THREAD_STATE_POLL : - { - //LOGINFO("POLL_THREAD_STATE_POLL"); - _instance->allocateLogicalAddress(DeviceType::TV); - if ( _instance->m_logicalAddressAllocated != LogicalAddress::UNREGISTERED) - { - logicalAddress = LogicalAddress(_instance->m_logicalAddressAllocated); - LibCCEC::getInstance().addLogicalAddress(logicalAddress); - _instance->smConnection->setSource(logicalAddress); - _instance->m_numberOfDevices = 0; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType = DeviceType::TV; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_isDevicePresent = true; - _instance->deviceList[_instance->m_logicalAddressAllocated].update(physical_addr); - _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_1_4; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_vendorID = appVendorId; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus = PowerStatus(powerState); - _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage = defaultLanguage; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_osdName = osdName.toString().c_str(); - if(cecVersion == 2.0) { - _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_2_0; - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), - MessageEncoder().encode(ReportFeatures(Version::V_2_0,allDevicetype,rcProfile,deviceFeatures)), 500); - } - _instance->smConnection->addFrameListener(_instance->msgFrameListener); - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), - MessageEncoder().encode(ReportPhysicalAddress(physical_addr, _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType)), 100); - - _instance->m_sleepTime = 0; - _instance->m_pollThreadState = POLL_THREAD_STATE_PING; - } - else - { - LOGINFO("Not able allocate Logical Address for TV"); - _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; - } - } - break; - - case POLL_THREAD_STATE_PING : - { - //LOGINFO("POLL_THREAD_STATE_PING"); - _instance->m_pollThreadState = POLL_THREAD_STATE_INFO; - connected.clear(); - disconnected.clear(); - _instance->pingDevices(connected, disconnected); - - if ( disconnected.size() ){ - for( unsigned int i=0; i< disconnected.size(); i++ ) - { - LOGWARN("Disconnected Devices [%zu]", disconnected.size()); - _instance->removeDevice(disconnected[i]); - } - } - - if (connected.size()) { - LOGWARN("Connected Devices [%zu]", connected.size()); - for( unsigned int i=0; i< connected.size(); i++ ) - { - _instance->addDevice(connected[i]); - /* If new device is connected, then try to aquire the information */ - _instance->m_pollThreadState = POLL_THREAD_STATE_INFO; - _instance->m_sleepTime = 0; - } - } - else - { - for(int i=0;im_logicalAddressAllocated && - _instance->deviceList[i].m_isDevicePresent && - !_instance->deviceList[i].isAllUpdated() ) - { - _instance->m_pollNextState = POLL_THREAD_STATE_INFO; - _instance->m_sleepTime = 0; - } - } - /* Check for any update required */ - _instance->m_pollThreadState = POLL_THREAD_STATE_UPDATE; - _instance->m_sleepTime = 0; - } - } - break; - - case POLL_THREAD_STATE_INFO : - { - //LOGINFO("POLL_THREAD_STATE_INFO"); - - if ( logicalAddressRequested == LogicalAddress::UNREGISTERED + TEST_ADD ) - { - int i = 0; - for(;im_logicalAddressAllocated && - _instance->deviceList[i].m_isDevicePresent && - !_instance->deviceList[i].isAllUpdated() ) - { - //LOGINFO("POLL_THREAD_STATE_INFO -> request for %d", i); - logicalAddressRequested = i; - _instance->request(logicalAddressRequested); - _instance->m_sleepTime = HDMICECSINK_REQUEST_INTERVAL_TIME_MS; - break; - } - } - - if ( i == LogicalAddress::UNREGISTERED) - { - /*So there is no update required, try to ping after some seconds*/ - _instance->m_pollThreadState = POLL_THREAD_STATE_IDLE; - _instance->m_sleepTime = 0; - //LOGINFO("POLL_THREAD_STATE_INFO -> state change to Ping", i); - } - } - else - { - /*So there is request sent for logical address, so wait and check the status */ - if ( _instance->requestStatus(logicalAddressRequested) == CECDeviceParams::REQUEST_DONE ) - { - logicalAddressRequested = LogicalAddress::UNREGISTERED; - } - else - { - _instance->m_sleepTime = HDMICECSINK_REQUEST_INTERVAL_TIME_MS; - } - } - } - break; - - /* updating the power status and if required we can add other information later*/ - case POLL_THREAD_STATE_UPDATE : - { - //LOGINFO("POLL_THREAD_STATE_UPDATE"); - - for(int i=0;im_logicalAddressAllocated && - _instance->deviceList[i].m_isDevicePresent && - _instance->deviceList[i].m_isPowerStatusUpdated ) - { - std::chrono::duration elapsed = std::chrono::system_clock::now() - _instance->deviceList[i].m_lastPowerUpdateTime; - - if ( elapsed.count() > HDMICECSINK_UPDATE_POWER_STATUS_INTERVA_MS ) - { - _instance->deviceList[i].m_isPowerStatusUpdated = false; - _instance->m_pollNextState = POLL_THREAD_STATE_INFO; - _instance->m_sleepTime = 0; - } - } - } - - _instance->m_pollThreadState = POLL_THREAD_STATE_IDLE; - _instance->m_sleepTime = 0; - } - break; - - case POLL_THREAD_STATE_IDLE : - { - //LOGINFO("POLL_THREAD_STATE_IDLE"); - _instance->m_sleepTime = HDMICECSINK_PING_INTERVAL_MS; - _instance->m_pollThreadState = POLL_THREAD_STATE_PING; - } - break; - - case POLL_THREAD_STATE_WAIT : - { - /* Wait for Hdmi is connected, in case it disconnected */ - //LOGINFO("19Aug2020-[01] -> POLL_THREAD_STATE_WAIT"); - _instance->m_sleepTime = HDMICECSINK_WAIT_FOR_HDMI_IN_MS; - - if ( _instance->m_isHdmiInConnected == true ) - { - _instance->m_pollThreadState = POLL_THREAD_STATE_POLL; - } - } - break; - - case POLL_THREAD_STATE_EXIT : - { - isExit = true; - _instance->m_sleepTime = 0; - } - break; - } - - std::unique_lock lk(_instance->m_pollExitMutex); - if ( _instance->m_ThreadExitCV.wait_for(lk, std::chrono::milliseconds(_instance->m_sleepTime)) == std::cv_status::timeout ) - continue; - else - LOGINFO("Thread is going to Exit m_pollThreadExit %d\n", _instance->m_pollThreadExit ); - - } - } - - void HdmiCecSink::allocateLAforTV() - { - bool gotLogicalAddress = false; - int addr = LogicalAddress::TV; - int i, j; - if (!(_instance->smConnection)) - return; - - for (i = 0; i< HDMICECSINK_NUMBER_TV_ADDR; i++) - { - /* poll for TV logical address - retry 5 times*/ - for (j = 0; j < 5; j++) - { - try { - smConnection->poll(LogicalAddress(addr), Throw_e()); - } - catch(CECNoAckException &e ) - { - LOGWARN("Poll caught %s \r\n",e.what()); - gotLogicalAddress = true; - break; - } - catch(Exception &e) - { - LOGWARN("Poll caught %s \r\n",e.what()); - usleep(250000); - } - } - if (gotLogicalAddress) - { - break; - } - addr = LogicalAddress::SPECIFIC_USE; - } - - if ( gotLogicalAddress ) - { - m_logicalAddressAllocated = addr; - } - else - { - m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; - } - - LOGWARN("Logical Address for TV 0x%x \r\n",m_logicalAddressAllocated); - } - - void HdmiCecSink::allocateLogicalAddress(int deviceType) - { - if( deviceType == DeviceType::TV ) - { - allocateLAforTV(); - } - } - - void HdmiCecSink::CECEnable(void) - { - std::lock_guard lock(m_enableMutex); - JsonObject params; - LOGINFO("Entered CECEnable"); - if (cecEnableStatus) - { - LOGWARN("CEC Already Enabled"); - return; - } - - if(0 == libcecInitStatus) - { - try - { - LibCCEC::getInstance().init("HdmiCecSink"); - } - catch (const std::exception& e) - { - LOGWARN("CEC exception caught from LibCCEC::getInstance().init()"); - } - } - libcecInitStatus++; - - //Acquire CEC Addresses - getPhysicalAddress(); - - smConnection = new Connection(LogicalAddress::UNREGISTERED,false,"ServiceManager::Connection::"); - smConnection->open(); - allocateLogicalAddress(DeviceType::TV); - LOGINFO("logical address allocalted: %x \n",m_logicalAddressAllocated); - if ( m_logicalAddressAllocated != LogicalAddress::UNREGISTERED && smConnection) - { - logicalAddress = LogicalAddress(m_logicalAddressAllocated); - LOGINFO(" add logical address %x \n",m_logicalAddressAllocated); - LibCCEC::getInstance().addLogicalAddress(logicalAddress); - smConnection->setSource(logicalAddress); - } - msgProcessor = new HdmiCecSinkProcessor(*smConnection); - msgFrameListener = new HdmiCecSinkFrameListener(*msgProcessor); - if(smConnection) - { - LOGWARN("Start Thread %p", smConnection ); - m_pollThreadState = POLL_THREAD_STATE_POLL; - m_pollNextState = POLL_THREAD_STATE_NONE; - m_pollThreadExit = false; - m_pollThread = std::thread(threadRun); - } - cecEnableStatus = true; - - params["cecEnable"] = string("true"); - sendNotify(eventString[HDMICECSINK_EVENT_CEC_ENABLED], params); - - return; - } - - void HdmiCecSink::CECDisable(void) - { - std::lock_guard lock(m_enableMutex); - JsonObject params; - LOGINFO("Entered CECDisable "); - if(!cecEnableStatus) - { - LOGWARN("CEC Already Disabled "); - return; - } - - if(m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED) - { - stopArc(); - while(m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED) - { - usleep(500000); - } - } - - LOGINFO(" CECDisable ARC stopped "); - cecEnableStatus = false; - if (smConnection != NULL) - { - LOGWARN("Stop Thread %p", smConnection ); - m_pollThreadExit = true; - m_ThreadExitCV.notify_one(); - - try - { - if (m_pollThread.joinable()) - { - LOGWARN("Join Thread %p", smConnection ); - m_pollThread.join(); - } - } - catch(const std::system_error& e) - { - LOGERR("system_error exception in thread join %s", e.what()); - } - catch(const std::exception& e) - { - LOGERR("exception in thread join %s", e.what()); - } - - m_pollThreadState = POLL_THREAD_STATE_NONE; - m_pollNextState = POLL_THREAD_STATE_NONE; - - LOGWARN("Deleted Thread %p", smConnection ); - - smConnection->close(); - delete smConnection; - smConnection = NULL; - } - - m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; - m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; - - for(int i=0; i< 16; i++) - { - if (_instance->deviceList[i].m_isDevicePresent) - { - _instance->deviceList[i].clear(); - } - } - - if(1 == libcecInitStatus) - { - try - { - LibCCEC::getInstance().term(); - } - catch (const std::exception& e) - { - LOGWARN("CEC exception caught from LibCCEC::getInstance().term() "); - } - } - - libcecInitStatus--; - LOGWARN("CEC Disabled %d",libcecInitStatus); - - params["cecEnable"] = string("false"); - sendNotify(eventString[HDMICECSINK_EVENT_CEC_ENABLED], params); - - return; - } - - - void HdmiCecSink::getPhysicalAddress() - { - LOGINFO("Entered getPhysicalAddress "); - - uint32_t physAddress = 0x0F0F0F0F; - - try { - LibCCEC::getInstance().getPhysicalAddress(&physAddress); - physical_addr = {(uint8_t)((physAddress >> 24) & 0xFF),(uint8_t)((physAddress >> 16) & 0xFF),(uint8_t) ((physAddress >> 8) & 0xFF),(uint8_t)((physAddress) & 0xFF)}; - LOGINFO("getPhysicalAddress: physicalAddress: %s ", physical_addr.toString().c_str()); - } - catch (const std::exception& e) - { - LOGWARN("exception caught from getPhysicalAddress"); - } - return; - } - - bool HdmiCecSink::getEnabled() - { - - - LOGINFO("getEnabled :%d ",cecEnableStatus); - if(true == cecEnableStatus) - return true; - else - return false; - } - - bool HdmiCecSink::getAudioDeviceConnectedStatus() - { - LOGINFO("getAudioDeviceConnectedStatus :%d ", hdmiCecAudioDeviceConnected); - if(true == hdmiCecAudioDeviceConnected) - return true; - else - return false; - } - //Arc Routing related functions - void HdmiCecSink::startArc() - { - if ( cecEnableStatus != true ) - { - LOGINFO("Initiate_Arc Cec is disabled-> EnableCEC first"); - return; - } - if(!HdmiCecSink::_instance) - return; - - LOGINFO("Current ARC State : %d\n", m_currentArcRoutingState); - - _instance->requestArcInitiation(); - - // start initiate ARC timer 3 sec - if (m_arcStartStopTimer.isActive()) - { - m_arcStartStopTimer.stop(); - } - m_arcstarting = true; - m_arcStartStopTimer.start((HDMISINK_ARC_START_STOP_MAX_WAIT_MS)); - - } - void HdmiCecSink::requestArcInitiation() - { - { - std::lock_guard lock(m_arcRoutingStateMutex); - m_currentArcRoutingState = ARC_STATE_REQUEST_ARC_INITIATION; - } - LOGINFO("requestArcInitiation release sem"); - _instance->m_semSignaltoArcRoutingThread.release(); - - } - void HdmiCecSink::stopArc() - { - if ( cecEnableStatus != true ) - { - LOGINFO("Initiate_Arc Cec is disabled-> EnableCEC first"); - return; - } - if(!HdmiCecSink::_instance) - return; - if(m_currentArcRoutingState == ARC_STATE_REQUEST_ARC_TERMINATION || m_currentArcRoutingState == ARC_STATE_ARC_TERMINATED) - { - LOGINFO("ARC is either Termination in progress or already Terminated"); - return; - } - - _instance->requestArcTermination(); - /* start a timer for 3 sec to get the desired ARC_STATE_ARC_TERMINATED */ - if (m_arcStartStopTimer.isActive()) - { - m_arcStartStopTimer.stop(); - } - /* m_arcstarting = true means starting the ARC start timer ,false means ARC stopping timer*/ - m_arcstarting = false; - m_arcStartStopTimer.start((HDMISINK_ARC_START_STOP_MAX_WAIT_MS)); - - - } - void HdmiCecSink::requestArcTermination() - { - { - std::lock_guard lock(m_arcRoutingStateMutex); - m_currentArcRoutingState = ARC_STATE_REQUEST_ARC_TERMINATION; - } - LOGINFO("requestArcTermination release sem"); - _instance->m_semSignaltoArcRoutingThread.release(); - - } - - void HdmiCecSink::Process_InitiateArc() - { - JsonObject params; - - LOGINFO("Command: INITIATE_ARC \n"); - - if(!HdmiCecSink::_instance) - return; - - //DD: Check cecSettingEnabled to prevent race conditions which gives immediate UI setting status - //Initiate ARC message may come from AVR/Soundbar while CEC disable is in-progress - if ( cecSettingEnabled != true ) - { - LOGINFO("Process InitiateArc from Audio device: Cec is disabled-> EnableCEC first"); - return; - } - - LOGINFO("Got : INITIATE_ARC and current Arcstate is %d\n",_instance->m_currentArcRoutingState); - - if (m_arcStartStopTimer.isActive()) - { - m_arcStartStopTimer.stop(); - } - if (powerState == DEVICE_POWER_STATE_ON ) { - LOGINFO("Notifying Arc Initiation event as power state is %s", powerState ? "Off" : "On"); - { - std::lock_guard lock(_instance->m_arcRoutingStateMutex); - _instance->m_currentArcRoutingState = ARC_STATE_ARC_INITIATED; - } - _instance->m_semSignaltoArcRoutingThread.release(); - LOGINFO("Got : ARC_INITIATED and notify Device setting"); - params["status"] = string("success"); - sendNotify(eventString[HDMICECSINK_EVENT_ARC_INITIATION_EVENT], params); - } else { - LOGINFO("Not notifying Arc Initiation event as power state is %s", powerState ? "Off" : "On"); - } - - } - void HdmiCecSink::Process_TerminateArc() - { - JsonObject params; - - LOGINFO("Command: TERMINATE_ARC current arc state %d \n",HdmiCecSink::_instance->m_currentArcRoutingState); - if (m_arcStartStopTimer.isActive()) - { - m_arcStartStopTimer.stop(); - } - { - std::lock_guard lock(m_arcRoutingStateMutex); - HdmiCecSink::_instance->m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; - } - _instance->m_semSignaltoArcRoutingThread.release(); - - // trigger callback to Device setting informing to TERMINATE_ARC - LOGINFO("Got : ARC_TERMINATED and notify Device setting"); - params["status"] = string("success"); - sendNotify(eventString[HDMICECSINK_EVENT_ARC_TERMINATION_EVENT], params); - } - - void HdmiCecSink::threadSendKeyEvent() - { - if(!HdmiCecSink::_instance) - return; - - SendKeyInfo keyInfo = {-1,-1}; - - while(!_instance->m_sendKeyEventThreadExit) - { - keyInfo.logicalAddr = -1; - keyInfo.keyCode = -1; - { - // Wait for a message to be added to the queue - std::unique_lock lk(_instance->m_sendKeyEventMutex); - _instance->m_sendKeyCV.wait(lk, []{return (_instance->m_sendKeyEventThreadRun == true);}); - } - - if (_instance->m_sendKeyEventThreadExit == true) - { - LOGINFO(" threadSendKeyEvent Exiting"); - _instance->m_sendKeyEventThreadRun = false; - break; - } - - if (_instance->m_SendKeyQueue.empty()) { - _instance->m_sendKeyEventThreadRun = false; - continue; - } - - keyInfo = _instance->m_SendKeyQueue.front(); - _instance->m_SendKeyQueue.pop(); - - if(keyInfo.UserControl == "sendUserControlPressed" ) - { - LOGINFO("sendUserControlPressed : logical addr:0x%x keyCode: 0x%x queue size :%zu \n",keyInfo.logicalAddr,keyInfo.keyCode,_instance->m_SendKeyQueue.size()); - _instance->sendUserControlPressed(keyInfo.logicalAddr,keyInfo.keyCode); - } - else if(keyInfo.UserControl == "sendUserControlReleased") - { - LOGINFO("sendUserControlReleased : logical addr:0x%x queue size :%zu \n",keyInfo.logicalAddr,_instance->m_SendKeyQueue.size()); - _instance->sendUserControlReleased(keyInfo.logicalAddr); - } - else - { - LOGINFO("sendKeyPressEvent : logical addr:0x%x keyCode: 0x%x queue size :%zu \n",keyInfo.logicalAddr,keyInfo.keyCode,_instance->m_SendKeyQueue.size()); - _instance->sendKeyPressEvent(keyInfo.logicalAddr,keyInfo.keyCode); - _instance->sendKeyReleaseEvent(keyInfo.logicalAddr); - } - - if((_instance->m_SendKeyQueue.size()<=1 || (_instance->m_SendKeyQueue.size() % 2 == 0)) && ((keyInfo.keyCode == VOLUME_UP) || (keyInfo.keyCode == VOLUME_DOWN) || (keyInfo.keyCode == MUTE)) ) - { - _instance->sendGiveAudioStatusMsg(); - } - - }//while(!_instance->m_sendKeyEventThreadExit) - }//threadSendKeyEvent - - - void HdmiCecSink::threadArcRouting() - { - bool isExit = false; - uint32_t currentArcRoutingState; - - if(!HdmiCecSink::_instance) - return; - - LOGINFO("Running threadArcRouting"); - - - while(1) - { - - _instance->m_semSignaltoArcRoutingThread.acquire(); - - - - { - LOGINFO(" threadArcRouting Got semaphore"); - std::lock_guard lock(_instance->m_arcRoutingStateMutex); - - currentArcRoutingState = _instance->m_currentArcRoutingState; - - LOGINFO(" threadArcRouting Got Sem arc state %d",currentArcRoutingState); - } - - switch (currentArcRoutingState) - { - - case ARC_STATE_REQUEST_ARC_INITIATION : - { - - _instance->systemAudioModeRequest(); - _instance->Send_Request_Arc_Initiation_Message(); - - } - break; - case ARC_STATE_ARC_INITIATED : - { - _instance->Send_Report_Arc_Initiated_Message(); - } - break; - case ARC_STATE_REQUEST_ARC_TERMINATION : - { - - _instance->Send_Request_Arc_Termination_Message(); - - } - break; - case ARC_STATE_ARC_TERMINATED : - { - _instance->Send_Report_Arc_Terminated_Message(); - } - break; - case ARC_STATE_ARC_EXIT : - { - isExit = true; - } - break; - } - - if (isExit == true) - { - LOGINFO(" threadArcRouting EXITing"); - break; - } - }//while(1) - }//threadArcRouting - - void HdmiCecSink::Send_Request_Arc_Initiation_Message() - { - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - LOGINFO(" Send_Request_Arc_Initiation_Message "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestArcInitiation()), 1000); - - } - void HdmiCecSink::Send_Report_Arc_Initiated_Message() - { - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(ReportArcInitiation()), 1000); - - } - void HdmiCecSink::Send_Request_Arc_Termination_Message() - { - - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestArcTermination()), 1000); - } - - void HdmiCecSink::Send_Report_Arc_Terminated_Message() - { - if(!HdmiCecSink::_instance) - return; - if(!(_instance->smConnection)) - return; - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(ReportArcTermination()), 1000); - - } - - void HdmiCecSink::getHdmiArcPortID() - { - int err; - dsGetHDMIARCPortIdParam_t param; - err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, - (char *)IARM_BUS_DSMGR_API_dsGetHDMIARCPortId, - (void *)¶m, - sizeof(param)); - if (IARM_RESULT_SUCCESS == err) - { - LOGINFO("HDMI ARC port ID HdmiArcPortID=[%d] \n", param.portId); - HdmiArcPortID = param.portId; - } - } - - void HdmiCecSink::getCecVersion() - { - RFC_ParamData_t param = {0}; - WDMP_STATUS status = getRFCParameter((char*)"thunderapi", TR181_HDMICECSINK_CEC_VERSION, ¶m); - if(WDMP_SUCCESS == status && param.type == WDMP_STRING) { - LOGINFO("CEC Version from RFC = [%s] \n", param.value); - cecVersion = atof(param.value); - } - else { - LOGINFO("Error while fetching CEC Version from RFC "); - } - } } // namespace Plugin } // namespace WPEFrameworklk diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index d41b16ab..84358a4a 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -20,456 +20,27 @@ #pragma once #include -#include "ccec/FrameListener.hpp" -#include "ccec/Connection.hpp" +#include +#include -#include "libIARM.h" -#include "ccec/Assert.hpp" -#include "ccec/Messages.hpp" -#include "ccec/MessageDecoder.hpp" -#include "ccec/MessageProcessor.hpp" +#include #undef Assert // this define from Connection.hpp conflicts with WPEFramework #include "Module.h" -#include "tptimer.h" -#include -#include -#include -#include -#include "UtilsLogging.h" -#include -#include "PowerManagerInterface.h" +#include "UtilsBIT.h" +#include "UtilsThreadRAII.h" -using namespace WPEFramework; -using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; -using ThermalTemperature = WPEFramework::Exchange::IPowerManager::ThermalTemperature; +#include +#include +#include +using namespace WPEFramework; namespace WPEFramework { namespace Plugin { - class HdmiCecSinkFrameListener : public FrameListener - { - public: - HdmiCecSinkFrameListener(MessageProcessor &processor) : processor(processor) {} - void notify(const CECFrame &in) const; - ~HdmiCecSinkFrameListener() {} - private: - MessageProcessor &processor; - }; - - class HdmiCecSinkProcessor : public MessageProcessor - { - public: - HdmiCecSinkProcessor(Connection &conn) : conn(conn) {} - void process (const ActiveSource &msg, const Header &header); - void process (const InActiveSource &msg, const Header &header); - void process (const ImageViewOn &msg, const Header &header); - void process (const TextViewOn &msg, const Header &header); - void process (const RequestActiveSource &msg, const Header &header); - void process (const Standby &msg, const Header &header); - void process (const GetCECVersion &msg, const Header &header); - void process (const CECVersion &msg, const Header &header); - void process (const SetMenuLanguage &msg, const Header &header); - void process (const GiveOSDName &msg, const Header &header); - void process (const GivePhysicalAddress &msg, const Header &header); - void process (const GiveDeviceVendorID &msg, const Header &header); - void process (const SetOSDString &msg, const Header &header); - void process (const SetOSDName &msg, const Header &header); - void process (const RoutingChange &msg, const Header &header); - void process (const RoutingInformation &msg, const Header &header); - void process (const SetStreamPath &msg, const Header &header); - void process (const GetMenuLanguage &msg, const Header &header); - void process (const ReportPhysicalAddress &msg, const Header &header); - void process (const DeviceVendorID &msg, const Header &header); - void process (const GiveDevicePowerStatus &msg, const Header &header); - void process (const ReportPowerStatus &msg, const Header &header); - void process (const FeatureAbort &msg, const Header &header); - void process (const Abort &msg, const Header &header); - void process (const Polling &msg, const Header &header); - void process (const InitiateArc &msg, const Header &header); - void process (const TerminateArc &msg, const Header &header); - void process (const ReportShortAudioDescriptor &msg, const Header &header); - void process (const SetSystemAudioMode &msg, const Header &header); - void process (const ReportAudioStatus &msg, const Header &header); - void process (const GiveFeatures &msg, const Header &header); - void process (const RequestCurrentLatency &msg, const Header &header); - private: - Connection conn; - void printHeader(const Header &header) - { - printf("Header : From : %s \n", header.from.toString().c_str()); - printf("Header : to : %s \n", header.to.toString().c_str()); - } - - }; - - class CECDeviceParams { - public: - - enum { - REQUEST_NONE = 0, - REQUEST_PHISICAL_ADDRESS = 1, - REQUEST_CEC_VERSION, - REQUEST_DEVICE_VENDOR_ID, - REQUEST_POWER_STATUS, - REQUEST_OSD_NAME, - }; - - enum { - REQUEST_DONE = 0, - REQUEST_NOT_DONE, - REQUEST_TIME_ELAPSED, - }; - - DeviceType m_deviceType; - LogicalAddress m_logicalAddress; - PhysicalAddress m_physicalAddr; - Version m_cecVersion; - VendorID m_vendorID; - OSDName m_osdName; - PowerStatus m_powerStatus; - bool m_isDevicePresent; - bool m_isDeviceDisconnected; - Language m_currentLanguage; - bool m_isActiveSource; - bool m_isDeviceTypeUpdated; - bool m_isPAUpdated; - bool m_isVersionUpdated; - bool m_isOSDNameUpdated; - bool m_isVendorIDUpdated; - bool m_isPowerStatusUpdated; - int m_isRequested; - int m_isRequestRetry; - std::chrono::system_clock::time_point m_requestTime; - std::vector m_featureAborts; - std::chrono::system_clock::time_point m_lastPowerUpdateTime; - - CECDeviceParams() - : m_deviceType(0), m_logicalAddress(0),m_physicalAddr(0x0f,0x0f,0x0f,0x0f),m_cecVersion(0),m_vendorID(0,0,0),m_osdName(""),m_powerStatus(0),m_currentLanguage("") - { - m_isDevicePresent = false; - m_isActiveSource = false; - m_isPAUpdated = false; - m_isVersionUpdated = false; - m_isOSDNameUpdated = false; - m_isVendorIDUpdated = false; - m_isPowerStatusUpdated = false; - m_isDeviceDisconnected = false; - m_isDeviceTypeUpdated = false; - m_isRequestRetry = 0; - } - - void clear( ) - { - m_deviceType = 0; - m_logicalAddress = 0; - m_physicalAddr = PhysicalAddress(0x0f,0x0f,0x0f,0x0f); - m_cecVersion = 0; - m_vendorID = VendorID(0,0,0); - m_osdName = ""; - m_powerStatus = 0; - m_currentLanguage = ""; - m_isDevicePresent = false; - m_isActiveSource = false; - m_isPAUpdated = false; - m_isVersionUpdated = false; - m_isOSDNameUpdated = false; - m_isVendorIDUpdated = false; - m_isPowerStatusUpdated = false; - m_isDeviceDisconnected = false; - m_isDeviceTypeUpdated = false; - } - - void printVariable() - { - LOGWARN("Device LogicalAddress %s", m_logicalAddress.toString().c_str()); - LOGWARN("Device Type %s", m_deviceType.toString().c_str()); - LOGWARN("Device Present %d", m_isDevicePresent); - LOGWARN("Active Source %d", m_isActiveSource); - LOGWARN("PA Updated %d", m_isPAUpdated); - LOGWARN("Version Updated %d", m_isVersionUpdated); - LOGWARN("OSDName Updated %d", m_isOSDNameUpdated); - LOGWARN("PowerStatus Updated %d", m_isPowerStatusUpdated); - LOGWARN("VendorID Updated %d", m_isPowerStatusUpdated); - LOGWARN("CEC Version : %s", m_cecVersion.toString().c_str()); - LOGWARN("Vendor ID : %s", m_vendorID.toString().c_str()); - LOGWARN("PhisicalAddress : %s", m_physicalAddr.toString().c_str()); - LOGWARN("OSDName : %s", m_osdName.toString().c_str()); - LOGWARN("Power Status : %s", m_powerStatus.toString().c_str()); - LOGWARN("Language : %s", m_currentLanguage.toString().c_str()); - } - - bool isAllUpdated() { - if( !m_isPAUpdated - || !m_isVersionUpdated - || !m_isOSDNameUpdated - || !m_isVendorIDUpdated - || !m_isPowerStatusUpdated - || !m_isDeviceTypeUpdated ){ - return false; - } - return true; - } - - void update( const DeviceType &deviceType ) { - m_deviceType = deviceType; - m_isDeviceTypeUpdated = true; - } - - void update( const PhysicalAddress &physical_addr ) { - m_physicalAddr = physical_addr; - m_isPAUpdated = true; - } - - void update ( const VendorID &vendorId) { - m_vendorID = vendorId; - m_isVendorIDUpdated = true; - } - - void update ( const Version &version ) { - m_cecVersion = version; - m_isVersionUpdated = true; - } - - void update ( const OSDName &osdName ) { - m_osdName = osdName; - m_isOSDNameUpdated = true; - } - - void update ( const PowerStatus &status ) { - m_powerStatus = status; - m_isPowerStatusUpdated = true; - m_lastPowerUpdateTime = std::chrono::system_clock::now(); - } - }; - - class DeviceNode { - public: - uint8_t m_childsLogicalAddr[LogicalAddress::UNREGISTERED]; - - DeviceNode() { - int i; - for (i = 0; i < LogicalAddress::UNREGISTERED; i++ ) - { - m_childsLogicalAddr[i] = LogicalAddress::UNREGISTERED; - } - } - - } ; - typedef struct sendKeyInfo - { - int logicalAddr; - int keyCode; - string UserControl; - }SendKeyInfo; - - class HdmiPortMap { - public: - uint8_t m_portID; - bool m_isConnected; - LogicalAddress m_logicalAddr; - PhysicalAddress m_physicalAddr; - DeviceNode m_deviceChain[3]; - - HdmiPortMap(uint8_t portID) : m_portID(portID), - m_logicalAddr(LogicalAddress::UNREGISTERED), - m_physicalAddr(portID+1,0,0,0) - { - m_isConnected = false; - } - - void update(bool isConnected) - { - m_isConnected = isConnected; - } - - void update( const LogicalAddress &addr ) - { - m_logicalAddr = addr; - } - - void addChild( const LogicalAddress &logical_addr, const PhysicalAddress &physical_addr ) - { - LOGINFO(" logicalAddr = %d, phisicalAddr = %s", m_logicalAddr.toInt(), physical_addr.toString().c_str()); - - if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED && - m_logicalAddr.toInt() != logical_addr.toInt() ) - { - LOGINFO(" update own logicalAddr = %d, new devcie logicalAddress = %d", m_logicalAddr.toInt(), logical_addr.toInt() ); - /* check matching with this port's physical address */ - if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && - physical_addr.getByteValue(1) != 0 ) - { - if ( physical_addr.getByteValue(3) != 0 ) - { - m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1] = logical_addr.toInt(); - } - else if ( physical_addr.getByteValue(2) != 0 ) - { - m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1] = logical_addr.toInt(); - } - else if ( physical_addr.getByteValue(1) != 0 ) - { - m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1] = logical_addr.toInt(); - } - } - } - else if ( physical_addr == m_physicalAddr ) - { - update(logical_addr); - LOGINFO(" update own logicalAddr = %d", m_logicalAddr.toInt()); - } - } - - void removeChild( PhysicalAddress &physical_addr ) - { - if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED ) - { - /* check matching with this port's physical address */ - if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && - physical_addr.getByteValue(1) != 0 ) - { - if ( physical_addr.getByteValue(3) != 0 ) - { - m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1] = LogicalAddress::UNREGISTERED; - } - else if ( physical_addr.getByteValue(2) != 0 ) - { - m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1] = LogicalAddress::UNREGISTERED; - } - else if ( physical_addr.getByteValue(1) != 0 ) - { - m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1] = LogicalAddress::UNREGISTERED; - } - } - } - } - - void getRoute( PhysicalAddress &physical_addr, std::vector & route ) - { - LOGINFO(" logicalAddr = %d, phsical = %s", m_logicalAddr.toInt(), physical_addr.toString().c_str()); - - if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED ) - { - LOGINFO(" search for logicalAddr = %d", m_logicalAddr.toInt()); - /* check matching with this port's physical address */ - if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && - physical_addr.getByteValue(1) != 0 ) - { - if ( physical_addr.getByteValue(3) != 0 ) - { - route.push_back(m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1]); - } - - if ( physical_addr.getByteValue(2) != 0 ) - { - route.push_back(m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1]); - } - - if ( physical_addr.getByteValue(1) != 0 ) - { - route.push_back(m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1]); - } - - route.push_back(m_logicalAddr.toInt()); - } - else - { - route.push_back(m_logicalAddr.toInt()); - LOGINFO("logicalAddr = %d, physical = %s", m_logicalAddr.toInt(), m_physicalAddr.toString().c_str()); - } - } - } - }; - - class binary_semaphore { - - public: - - explicit binary_semaphore(int init_count = count_max) - - : count_(init_count) {} - - - - // P-operation / acquire - - void wait() - - { - - std::unique_lock lk(m_); - - cv_.wait(lk, [=]{ return 0 < count_; }); - - --count_; - - } - - bool try_wait() - - { - - std::lock_guard lk(m_); - - if (0 < count_) { - - --count_; - - return true; - - } else { - - return false; - - } - - } - - // V-operation / release - - void signal() - - { - - std::lock_guard lk(m_); - - if (count_ < count_max) { - - ++count_; - - cv_.notify_one(); - - } - - } - - - - // Lockable requirements - - void acquire() { wait(); } - - bool try_lock() { return try_wait(); } - - void release() { signal(); } - - - -private: - - static const int count_max = 1; - - int count_; - - std::mutex m_; - - std::condition_variable cv_; - -}; // This is a server for a JSONRPC communication channel. // For a plugin to be capable to handle JSONRPC, inherit from PluginHost::JSONRPC. // By inheriting from this class, the plugin realizes the interface PluginHost::IDispatcher. @@ -484,257 +55,211 @@ namespace WPEFramework { // will receive a JSONRPC message as a notification, in case this method is called. class HdmiCecSink : public PluginHost::IPlugin, public PluginHost::JSONRPC { - enum { - POLL_THREAD_STATE_NONE, - POLL_THREAD_STATE_IDLE, - POLL_THREAD_STATE_POLL, - POLL_THREAD_STATE_PING, - POLL_THREAD_STATE_INFO, - POLL_THREAD_STATE_WAIT, - POLL_THREAD_STATE_CLEAN, - POLL_THREAD_STATE_UPDATE, - POLL_THREAD_STATE_EXIT, - }; - enum { - ARC_STATE_REQUEST_ARC_INITIATION, - ARC_STATE_ARC_INITIATED, - ARC_STATE_REQUEST_ARC_TERMINATION, - ARC_STATE_ARC_TERMINATED, - ARC_STATE_ARC_EXIT - }; - enum { - VOLUME_UP = 0x41, - VOLUME_DOWN = 0x42, - MUTE = 0x43, - UP = 0x01, - DOWN = 0x02, - LEFT = 0x03, - RIGHT = 0x04, - SELECT = 0x00, - HOME = 0x09, - BACK = 0x0D, - NUMBER_0 = 0x20, - NUMBER_1 = 0x21, - NUMBER_2 = 0x22, - NUMBER_3 = 0x23, - NUMBER_4 = 0x24, - NUMBER_5 = 0x25, - NUMBER_6 = 0x26, - NUMBER_7 = 0x27, - NUMBER_8 = 0x28, - NUMBER_9 = 0x29 - }; - public: - HdmiCecSink(); - virtual ~HdmiCecSink(); - virtual const string Initialize(PluginHost::IShell* shell) override; - virtual void Deinitialize(PluginHost::IShell* service) override; - virtual string Information() const override { return {}; } - static HdmiCecSink* _instance; - CECDeviceParams deviceList[16]; - std::vector hdmiInputs; - int m_currentActiveSource; - void updateInActiveSource(const int logical_address, const InActiveSource &source ); - void updateActiveSource(const int logical_address, const ActiveSource &source ); - void updateTextViewOn(const int logicalAddress); - void updateImageViewOn(const int logicalAddress); - void updateDeviceChain(const LogicalAddress &logicalAddress, const PhysicalAddress &phy_addr); - void getActiveRoute(const LogicalAddress &logicalAddress, std::vector &route); - void removeDevice(const int logicalAddress); - void addDevice(const int logicalAddress); - void printDeviceList(); - void setStreamPath( const PhysicalAddress &physical_addr); - void setRoutingChange(const std::string &from, const std::string &to); - void sendStandbyMessage(); - void setCurrentLanguage(const Language &lang); - void sendMenuLanguage(); - void setActiveSource(bool isResponse); - void requestActiveSource(); - void startArc(); - void stopArc(); - void Process_InitiateArc(); - void Process_TerminateArc(); - void updateArcState(); - void requestShortaudioDescriptor(); - void Send_ShortAudioDescriptor_Event(JsonArray audiodescriptor); - void Process_ShortAudioDescriptor_msg(const ReportShortAudioDescriptor &msg); - void Process_SetSystemAudioMode_msg(const SetSystemAudioMode &msg); - void sendDeviceUpdateInfo(const int logicalAddress); - void sendFeatureAbort(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason); - void reportFeatureAbortEvent(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason); - void systemAudioModeRequest(); - void SendStandbyMsgEvent(const int logicalAddress); - void requestAudioDevicePowerStatus(); - void reportAudioDevicePowerStatusInfo(const int logicalAddress, const int powerStatus); - void updateCurrentLatency(int videoLatency, bool lowLatencyMode, int audioOutputCompensated, int audioOutputDelay); - void setLatencyInfo(); - void Process_ReportAudioStatus_msg(const ReportAudioStatus msg); - void sendKeyPressEvent(const int logicalAddress, int keyCode); - void sendKeyReleaseEvent(const int logicalAddress); - void sendUserControlPressed(const int logicalAddress, int keyCode); - void sendUserControlReleased(const int logicalAddress); - void sendGiveAudioStatusMsg(); - void onPowerModeChanged(const PowerState ¤tState, const PowerState &newState); - void registerEventHandlers(); - int m_numberOfDevices; /* Number of connected devices othethan own device */ - bool m_audioDevicePowerStatusRequested; - - BEGIN_INTERFACE_MAP(HdmiCecSink) - INTERFACE_ENTRY(PluginHost::IPlugin) - INTERFACE_ENTRY(PluginHost::IDispatcher) - END_INTERFACE_MAP - - private: - class PowerManagerNotification : public Exchange::IPowerManager::IModeChangedNotification { private: - PowerManagerNotification(const PowerManagerNotification&) = delete; - PowerManagerNotification& operator=(const PowerManagerNotification&) = delete; + class Notification : public RPC::IRemoteConnection::INotification, + public Exchange::IHdmiCecSink::INotification + { + private: + Notification() = delete; + Notification(const Notification&) = delete; + Notification& operator=(const Notification&) = delete; + + public: + explicit Notification(HdmiCecSink* parent) + : _parent(*parent) + { + ASSERT(parent != nullptr); + } + + virtual ~Notification() + { + } + + BEGIN_INTERFACE_MAP(Notification) + INTERFACE_ENTRY(Exchange::IHdmiCecSink::INotification) + INTERFACE_ENTRY(RPC::IRemoteConnection::INotification) + END_INTERFACE_MAP + + void Activated(RPC::IRemoteConnection*) override + { + } + + void Deactivated(RPC::IRemoteConnection *connection) override + { + _parent.Deactivated(connection); + } + + void ArcInitiationEvent(const string success) override + { + LOGINFO("ArcInitiationEvent"); + LOGINFO("success: %s", success.c_str()); + Exchange::JHdmiCecSink::Event::ArcInitiationEvent(_parent, success); + } + + void ArcTerminationEvent(const string success) override + { + LOGINFO("ArcTerminationEvent"); + LOGINFO("success: %s", success.c_str()); + Exchange::JHdmiCecSink::Event::ArcTerminationEvent(_parent, success); + } + + void OnActiveSourceChange(const int logicalAddress, const string physicalAddress) override + { + LOGINFO("OnActiveSourceChange"); + LOGINFO("logicalAddress: %d, physicalAddress: %s", logicalAddress, physicalAddress.c_str()); + Exchange::JHdmiCecSink::Event::OnActiveSourceChange(_parent, logicalAddress, physicalAddress); + } + + void OnDeviceAdded(const int logicalAddress) override + { + LOGINFO("OnDeviceAdded"); + LOGINFO("logicalAddress: %d", logicalAddress); + Exchange::JHdmiCecSink::Event::OnDeviceAdded(_parent, logicalAddress); + } + + void OnDeviceInfoUpdated(const int logicalAddress) override + { + LOGINFO("OnDeviceInfoUpdated"); + LOGINFO("logicalAddress: %d", logicalAddress); + Exchange::JHdmiCecSink::Event::OnDeviceInfoUpdated(_parent, logicalAddress); + } + + void OnDeviceRemoved(const int logicalAddress) override + { + LOGINFO("OnDeviceRemoved"); + LOGINFO("logicalAddress: %d", logicalAddress); + Exchange::JHdmiCecSink::Event::OnDeviceRemoved(_parent, logicalAddress); + } + + void OnImageViewOnMsg(const int logicalAddress) override + { + LOGINFO("OnImageViewOnMsg"); + LOGINFO("logicalAddress: %d", logicalAddress); + Exchange::JHdmiCecSink::Event::OnImageViewOnMsg(_parent, logicalAddress); + } + + void OnInActiveSource(const int logicalAddress, const string physicalAddress) override + { + LOGINFO("OnInActiveSource"); + LOGINFO("logicalAddress: %d, physicalAddress: %s", logicalAddress, physicalAddress.c_str()); + Exchange::JHdmiCecSink::Event::OnInActiveSource(_parent, logicalAddress, physicalAddress); + } + + void OnTextViewOnMsg(const int logicalAddress) override + { + LOGINFO("OnTextViewOnMsg"); + LOGINFO("logicalAddress: %d", logicalAddress); + Exchange::JHdmiCecSink::Event::OnTextViewOnMsg(_parent, logicalAddress); + } + + void OnWakeupFromStandby(const int logicalAddress) override + { + LOGINFO("OnWakeupFromStandby"); + LOGINFO("logicalAddress: %d", logicalAddress); + Exchange::JHdmiCecSink::Event::OnWakeupFromStandby(_parent, logicalAddress); + } + + void ReportAudioDeviceConnectedStatus(const string status, const string audioDeviceConnected) override + { + LOGINFO("ReportAudioDeviceConnectedStatus"); + LOGINFO("status: %s, audioDeviceConnected: %s", status.c_str(), audioDeviceConnected.c_str()); + Exchange::JHdmiCecSink::Event::ReportAudioDeviceConnectedStatus(_parent, status, audioDeviceConnected); + } + + void ReportAudioStatusEvent(const int muteStatus, const int volumeLevel) override + { + LOGINFO("ReportAudioStatusEvent"); + LOGINFO("muteStatus: %d, volumeLevel: %d", muteStatus, volumeLevel); + Exchange::JHdmiCecSink::Event::ReportAudioStatusEvent(_parent, muteStatus, volumeLevel); + } + + void ReportFeatureAbortEvent(const int logicalAddress, const int opcode, const int FeatureAbortReason) override + { + LOGINFO("ReportFeatureAbortEvent"); + LOGINFO("logicalAddress: %d, opcode: %d, FeatureAbortReason: %d", logicalAddress, opcode, FeatureAbortReason); + Exchange::JHdmiCecSink::Event::ReportFeatureAbortEvent(_parent, logicalAddress, opcode, FeatureAbortReason); + } + + void ReportCecEnabledEvent(const string cecEnable) override + { + LOGINFO("ReportCecEnabledEvent"); + LOGINFO("cecEnable: %s", cecEnable.c_str()); + Exchange::JHdmiCecSink::Event::ReportCecEnabledEvent(_parent, cecEnable); + } + + void SetSystemAudioModeEvent(const string audioMode) override + { + LOGINFO("SetSystemAudioModeEvent"); + LOGINFO("audioMode: %s", audioMode.c_str()); + Exchange::JHdmiCecSink::Event::SetSystemAudioModeEvent(_parent, audioMode); + } + + void ShortAudiodescriptorEvent(IHdmiCecSinkShortAudioDescriptorIterator* ShortAudioDescriptor) override + { + LOGINFO("ShortAudiodescriptorEvent"); + Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, ShortAudioDescriptor); + } + + void StandbyMessageReceived(const int logicalAddress) override + { + LOGINFO("StandbyMessageReceived"); + LOGINFO("logicalAddress: %d", logicalAddress); + Exchange::JHdmiCecSink::Event::StandbyMessageReceived(_parent, logicalAddress); + } + + void ReportAudioDevicePowerStatus(const int powerStatus) override + { + LOGINFO("ReportAudioDevicePowerStatus"); + LOGINFO("powerStatus: %d", powerStatus); + Exchange::JHdmiCecSink::Event::ReportAudioDevicePowerStatus(_parent, powerStatus); + } + + private: + HdmiCecSink &_parent; + + }; public: - explicit PowerManagerNotification(HdmiCecSink& parent) - : _parent(parent) + // We do not allow this plugin to be copied !! + HdmiCecSink(const HdmiCecSink&) = delete; + HdmiCecSink& operator=(const HdmiCecSink&) = delete; + + HdmiCecSink() + : PluginHost::IPlugin() + , PluginHost::JSONRPC() + , _service(nullptr) + , _notification(this) + , _hdmiCecSink(nullptr) + , _connectionId(0) { - } - ~PowerManagerNotification() override = default; - public: - void OnPowerModeChanged(const PowerState ¤tState, const PowerState &newState) override - { - _parent.onPowerModeChanged(currentState, newState); } - - template - T* baseInterface() + virtual ~HdmiCecSink() { - static_assert(std::is_base_of(), "base type mismatch"); - return static_cast(this); + } - - BEGIN_INTERFACE_MAP(PowerManagerNotification) - INTERFACE_ENTRY(Exchange::IPowerManager::IModeChangedNotification) + + BEGIN_INTERFACE_MAP(HdmiCecSink) + INTERFACE_ENTRY(PluginHost::IPlugin) + INTERFACE_ENTRY(PluginHost::IDispatcher) + INTERFACE_AGGREGATE(Exchange::IHdmiCecSink, _hdmiCecSink) END_INTERFACE_MAP + // IPlugin methods + // ------------------------------------------------------------------------------------------------------- + const string Initialize(PluginHost::IShell* service) override; + void Deinitialize(PluginHost::IShell* service) override; + string Information() const override; + //Begin methods + + private: + void Deactivated(RPC::IRemoteConnection* connection); + private: - HdmiCecSink& _parent; - }; - // We do not allow this plugin to be copied !! - HdmiCecSink(const HdmiCecSink&) = delete; - HdmiCecSink& operator=(const HdmiCecSink&) = delete; - - //Begin methods - uint32_t setEnabledWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getEnabledWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setOSDNameWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getOSDNameWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setVendorIdWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getVendorIdWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t printDeviceListWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setActivePathWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setRoutingChangeWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getDeviceListWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getActiveSourceWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setActiveSourceWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getActiveRouteWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t requestActiveSourceWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setArcEnableDisableWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setMenuLanguageWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t requestShortAudioDescriptorWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t sendStandbyMessageWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t sendAudioDevicePowerOnMsgWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t sendRemoteKeyPressWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t sendUserControlPressedWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t sendUserControlReleasedWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t sendGiveAudioStatusWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t getAudioDeviceConnectedStatusWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t requestAudioDevicePowerStatusWrapper(const JsonObject& parameters, JsonObject& response); - uint32_t setLatencyInfoWrapper(const JsonObject& parameters, JsonObject& response); - void InitializePowerManager(PluginHost::IShell *service); - //End methods - std::string logicalAddressDeviceType; - bool cecSettingEnabled; - bool cecOTPSettingEnabled; - bool cecEnableStatus; - bool hdmiCecAudioDeviceConnected; - bool m_isHdmiInConnected; - int m_numofHdmiInput; - uint8_t m_deviceType; - int m_logicalAddressAllocated; - std::thread m_pollThread; - uint32_t m_pollThreadState; - uint32_t m_pollNextState; - bool m_pollThreadExit; - uint32_t m_sleepTime; - std::mutex m_pollExitMutex; - std::mutex m_enableMutex; - /* Send Key event related */ - bool m_sendKeyEventThreadExit; - bool m_sendKeyEventThreadRun; - std::thread m_sendKeyEventThread; - std::mutex m_sendKeyEventMutex; - std::queue m_SendKeyQueue; - std::condition_variable m_sendKeyCV; - std::condition_variable m_ThreadExitCV; - - /* DALS - Latency Values */ - uint8_t m_video_latency; - uint8_t m_latency_flags; - uint8_t m_audio_output_delay; - - /* ARC related */ - std::thread m_arcRoutingThread; - uint32_t m_currentArcRoutingState; - std::mutex m_arcRoutingStateMutex; - binary_semaphore m_semSignaltoArcRoutingThread; - bool m_arcstarting; - TpTimer m_arcStartStopTimer; - - Connection *smConnection; - std::vector m_connectedDevices; - HdmiCecSinkProcessor *msgProcessor; - HdmiCecSinkFrameListener *msgFrameListener; - PowerManagerInterfaceRef _powerManagerPlugin; - Core::Sink _pwrMgrNotification; - bool _registeredEventHandlers; - const void InitializeIARM(); - void DeinitializeIARM(); - void allocateLogicalAddress(int deviceType); - void allocateLAforTV(); - void pingDevices(std::vector &connected , std::vector &disconnected); - void CheckHdmiInState(); - void request(const int logicalAddress); - int requestType(const int logicalAddress); - int requestStatus(const int logicalAddress); - static void threadRun(); - void cecMonitoringThread(); - static void dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); - void onHdmiHotPlug(int portId, int connectStatus); - bool loadSettings(); - void persistSettings(bool enableStatus); - void persistOTPSettings(bool enableStatus); - void persistOSDName(const char *name); - void persistVendorId(unsigned int vendorID); - void setEnabled(bool enabled); - bool getEnabled(); - bool getAudioDeviceConnectedStatus(); - void CECEnable(void); - void CECDisable(void); - void getPhysicalAddress(); - void getLogicalAddress(); - void cecAddressesChanged(int changeStatus); - - // Arc functions - - static void threadSendKeyEvent(); - static void threadArcRouting(); - void requestArcInitiation(); - void requestArcTermination(); - void Send_Request_Arc_Initiation_Message(); - void Send_Report_Arc_Initiated_Message(); - void Send_Request_Arc_Termination_Message(); - void Send_Report_Arc_Terminated_Message(); - void arcStartStopTimerFunction(); - void getHdmiArcPortID(); - void getCecVersion(); + PluginHost::IShell* _service{}; + Core::Sink _notification; + Exchange::IHdmiCecSink* _hdmiCecSink; + uint32_t _connectionId; }; } // namespace Plugin } // namespace WPEFramework diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp new file mode 100644 index 00000000..0cee5ade --- /dev/null +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -0,0 +1,3401 @@ +/** +* If not stated otherwise in this file or this component's LICENSE +* file the following copyright and licenses apply: +* +* Copyright 2019 RDK Management +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +#include "HdmiCecSinkImplementation.h" + +#include "ccec/Connection.hpp" +#include "ccec/CECFrame.hpp" +#include "ccec/MessageEncoder.hpp" +#include "host.hpp" +#include "UtilsgetRFCConfig.h" + +#include "dsMgr.h" +#include "dsRpc.h" +#include "dsDisplay.h" +#include "videoOutputPort.hpp" +#include "manager.hpp" +#include "websocket/URL.h" + +#include "UtilsIarm.h" +#include "UtilsJsonRpc.h" +#include "UtilssyncPersistFile.h" +#include "UtilsSearchRDKProfile.h" + +#define TEST_ADD 0 +#define HDMICECSINK_REQUEST_MAX_RETRY 3 +#define HDMICECSINK_REQUEST_MAX_WAIT_TIME_MS 2000 +#define HDMICECSINK_PING_INTERVAL_MS 10000 +#define HDMICECSINK_WAIT_FOR_HDMI_IN_MS 1000 +#define HDMICECSINK_REQUEST_INTERVAL_TIME_MS 500 +#define HDMICECSINK_NUMBER_TV_ADDR 2 +#define HDMICECSINK_UPDATE_POWER_STATUS_INTERVA_MS (60 * 1000) +#define HDMISINK_ARC_START_STOP_MAX_WAIT_MS 4000 + + +#define SAD_FMT_CODE_AC3 2 +#define SAD_FMT_CODE_ENHANCED_AC3 10 + +#define SYSTEM_AUDIO_MODE_ON 0x01 +#define SYSTEM_AUDIO_MODE_OFF 0x00 +#define AUDIO_DEVICE_POWERSTATE_OFF 1 + +#define DEFAULT_VIDEO_LATENCY 100 +#define DEFAULT_LATENCY_FLAGS 3 +#define DEFAULT_AUDIO_OUTPUT_DELAY 100 + +//Device Type is TV - Bit 7 is set to 1 +#define ALL_DEVICE_TYPES 128 + +//RC Profile of TV is 3 - Typical TV Remote +#define RC_PROFILE_TV 10 + +//Device Features supported by TV - ARC Tx +#define DEVICE_FEATURES_TV 4 + +#define TR181_HDMICECSINK_CEC_VERSION "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.HdmiCecSink.CECVersion" + + +#define CEC_SETTING_ENABLED_FILE "/opt/persistent/ds/cecData_2.json" +#define CEC_SETTING_OTP_ENABLED "cecOTPEnabled" +#define CEC_SETTING_ENABLED "cecEnabled" +#define CEC_SETTING_OSD_NAME "cecOSDName" +#define CEC_SETTING_VENDOR_ID "cecVendorId" + +static std::vector defaultVendorId = {0x00,0x19,0xFB}; +static VendorID appVendorId = {defaultVendorId.at(0),defaultVendorId.at(1),defaultVendorId.at(2)}; +static VendorID lgVendorId = {0x00,0xE0,0x91}; +static PhysicalAddress physical_addr = {0x0F,0x0F,0x0F,0x0F}; +static LogicalAddress logicalAddress = 0xF; +static Language defaultLanguage = "eng"; +static OSDName osdName = "TV Box"; +static int32_t powerState = DEVICE_POWER_STATE_OFF; +static std::vector formatid = {0,0}; +static std::vector audioFormatCode = { SAD_FMT_CODE_ENHANCED_AC3,SAD_FMT_CODE_AC3 }; +static uint8_t numberofdescriptor = 2; +static int32_t HdmiArcPortID = -1; +static float cecVersion = 1.4; +static AllDeviceTypes allDevicetype = ALL_DEVICE_TYPES; +static std::vector rcProfile = {RC_PROFILE_TV}; +static std::vector deviceFeatures = {DEVICE_FEATURES_TV}; + +#define API_VERSION_NUMBER_MAJOR 1 +#define API_VERSION_NUMBER_MINOR 3 +#define API_VERSION_NUMBER_PATCH 7 + +using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; + +namespace WPEFramework +{ + namespace { + + static Plugin::Metadata metadata( + // Version (Major, Minor, Patch) + API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH, + // Preconditions + {}, + // Terminations + {}, + // Controls + {} + ); + } + + namespace Plugin + { + SERVICE_REGISTRATION(HdmiCecSink, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); + + HdmiCecSink* HdmiCecSinkImplementation::_instance = nullptr; + static int libcecInitStatus = 0; + +//=========================================== HdmiCecSinkFrameListener ========================================= + void HdmiCecSinkFrameListener::notify(const CECFrame &in) const { + const uint8_t *buf = NULL; + char strBuffer[512] = {0}; + size_t len = 0; + + in.getBuffer(&buf, &len); + for (unsigned int i = 0; i < len; i++) { + snprintf(strBuffer + (i*3) , sizeof(strBuffer) - (i*3), "%02X ",(uint8_t) *(buf + i)); + } + LOGINFO(" >>>>> Received CEC Frame: :%s \n",strBuffer); + + MessageDecoder(processor).decode(in); + } + +//=========================================== HdmiCecSinkProcessor ========================================= + void HdmiCecSinkProcessor::process (const ActiveSource &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: ActiveSource %s : %s : %s \n",GetOpName(msg.opCode()),msg.physicalAddress.name().c_str(),msg.physicalAddress.toString().c_str()); + if(!(header.to == LogicalAddress(LogicalAddress::BROADCAST))){ + LOGINFO("Ignore Direct messages, accepts only broadcast messages"); + return; + } + HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); + HdmiCecSinkImplementation::_instance->updateActiveSource(header.from.toInt(), msg); + } + void HdmiCecSinkProcessor::process (const InActiveSource &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: InActiveSource %s : %s : %s \n",GetOpName(msg.opCode()),msg.physicalAddress.name().c_str(),msg.physicalAddress.toString().c_str()); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + + HdmiCecSinkImplementation::_instance->updateInActiveSource(header.from.toInt(), msg); + } + + void HdmiCecSinkProcessor::process (const ImageViewOn &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: ImageViewOn from %s\n", header.from.toString().c_str()); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); + HdmiCecSinkImplementation::_instance->updateImageViewOn(header.from.toInt()); + } + void HdmiCecSinkProcessor::process (const TextViewOn &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: TextViewOn\n"); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); + HdmiCecSinkImplementation::_instance->updateTextViewOn(header.from.toInt()); + } + void HdmiCecSinkProcessor::process (const RequestActiveSource &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: RequestActiveSource\n"); + if(!(header.to == LogicalAddress(LogicalAddress::BROADCAST))){ + LOGINFO("Ignore Direct messages, accepts only broadcast messages"); + return; + } + + HdmiCecSinkImplementation::_instance->setActiveSource(true); + } + void HdmiCecSinkProcessor::process (const Standby &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: Standby from %s\n", header.from.toString().c_str()); + HdmiCecSinkImplementation::_instance->SendStandbyMsgEvent(header.from.toInt()); + } + void HdmiCecSinkProcessor::process (const GetCECVersion &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: GetCECVersion sending CECVersion response \n"); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + try + { + if(cecVersion == 2.0) { + conn.sendToAsync(header.from, MessageEncoder().encode(CECVersion(Version::V_2_0))); + } + else{ + conn.sendToAsync(header.from, MessageEncoder().encode(CECVersion(Version::V_1_4))); + } + } + catch(...) + { + LOGWARN("Exception while sending CECVersion "); + } + } + void HdmiCecSinkProcessor::process (const CECVersion &msg, const Header &header) + { + bool updateStatus; + printHeader(header); + LOGINFO("Command: CECVersion Version : %s \n",msg.version.toString().c_str()); + + HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); + updateStatus = HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isVersionUpdated; + LOGINFO("updateStatus %d\n",updateStatus); + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(msg.version); + if(!updateStatus) + HdmiCecSinkImplementation::_instance->sendDeviceUpdateInfo(header.from.toInt()); + } + void HdmiCecSinkProcessor::process (const SetMenuLanguage &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: SetMenuLanguage Language : %s \n",msg.language.toString().c_str()); + } + void HdmiCecSinkProcessor::process (const GiveOSDName &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: GiveOSDName sending SetOSDName : %s\n",osdName.toString().c_str()); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + try + { + conn.sendToAsync(header.from, MessageEncoder().encode(SetOSDName(osdName))); + } + catch(...) + { + LOGWARN("Exception while sending SetOSDName"); + } + } + void HdmiCecSinkProcessor::process (const GivePhysicalAddress &msg, const Header &header) + { + LOGINFO("Command: GivePhysicalAddress\n"); + if (!(header.to == LogicalAddress(LogicalAddress::BROADCAST))) + { + try + { + LOGINFO(" sending ReportPhysicalAddress response physical_addr :%s logicalAddress :%x \n",physical_addr.toString().c_str(), logicalAddress.toInt()); + conn.sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(ReportPhysicalAddress(physical_addr,logicalAddress.toInt())), 500); + } + catch(...) + { + LOGWARN("Exception while sending ReportPhysicalAddress "); + } + } + } + void HdmiCecSinkProcessor::process (const GiveDeviceVendorID &msg, const Header &header) + { + printHeader(header); + if(header.to == LogicalAddress(LogicalAddress::BROADCAST)){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + try + { + LOGINFO("Command: GiveDeviceVendorID sending VendorID response :%s\n",appVendorId.toString().c_str()); + conn.sendToAsync(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(DeviceVendorID(appVendorId))); + } + catch(...) + { + LOGWARN("Exception while sending DeviceVendorID"); + } + + } + void HdmiCecSinkProcessor::process (const SetOSDString &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: SetOSDString OSDString : %s\n",msg.osdString.toString().c_str()); + } + void HdmiCecSinkProcessor::process (const SetOSDName &msg, const Header &header) + { + printHeader(header); + bool updateStatus ; + LOGINFO("Command: SetOSDName OSDName : %s\n",msg.osdName.toString().c_str()); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + + HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); + updateStatus = HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isOSDNameUpdated; + LOGINFO("updateStatus %d\n",updateStatus); + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(msg.osdName); + if(HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isRequestRetry > 0 && + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isRequested == CECDeviceParams::REQUEST_OSD_NAME) { + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isRequestRetry = 0; + } + if(!updateStatus) + HdmiCecSinkImplementation::_instance->sendDeviceUpdateInfo(header.from.toInt()); + } + void HdmiCecSinkProcessor::process (const RoutingChange &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: RoutingChange From : %s To: %s \n",msg.from.toString().c_str(),msg.to.toString().c_str()); + } + void HdmiCecSinkProcessor::process (const RoutingInformation &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: RoutingInformation Routing Information to Sink : %s\n",msg.toSink.toString().c_str()); + } + void HdmiCecSinkProcessor::process (const SetStreamPath &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: SetStreamPath Set Stream Path to Sink : %s\n",msg.toSink.toString().c_str()); + } + void HdmiCecSinkProcessor::process (const GetMenuLanguage &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: GetMenuLanguage\n"); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + HdmiCecSinkImplementation::_instance->sendMenuLanguage(); + } + void HdmiCecSinkProcessor::process (const ReportPhysicalAddress &msg, const Header &header) + { + printHeader(header); + bool updateDeviceTypeStatus; + bool updatePAStatus; + LOGINFO("Command: ReportPhysicalAddress\n"); + if(!(header.to == LogicalAddress(LogicalAddress::BROADCAST))){ + LOGINFO("Ignore Direct messages, accepts only broadcast messages"); + return; + } + + if(!HdmiCecSinkImplementation::_instance) + return; + HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); + updateDeviceTypeStatus = HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isDeviceTypeUpdated; + updatePAStatus = HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isPAUpdated; + LOGINFO("updateDeviceTypeStatus %d updatePAStatus %d \n",updateDeviceTypeStatus,updatePAStatus); + if(HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_physicalAddr.toString() != msg.physicalAddress.toString() && updatePAStatus){ + updatePAStatus= false; + LOGINFO("There is a change in physical address from current PA %s to newly reported PA %s\n",HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_physicalAddr.toString().c_str(),msg.physicalAddress.toString().c_str()); + } + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(msg.physicalAddress); + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(msg.deviceType); + if(HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isRequestRetry > 0 && + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isRequested == CECDeviceParams::REQUEST_PHISICAL_ADDRESS) { + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isRequestRetry = 0; + } + HdmiCecSinkImplementation::_instance->updateDeviceChain(header.from, msg.physicalAddress); + if (!updateDeviceTypeStatus || !updatePAStatus) + HdmiCecSinkImplementation::_instance->sendDeviceUpdateInfo(header.from.toInt()); + } + void HdmiCecSinkProcessor::process (const DeviceVendorID &msg, const Header &header) + { + bool updateStatus ; + printHeader(header); + LOGINFO("Command: DeviceVendorID VendorID : %s\n",msg.vendorId.toString().c_str()); + if(!(header.to == LogicalAddress(LogicalAddress::BROADCAST))){ + LOGINFO("Ignore Direct messages, accepts only broadcast messages"); + return; + } + + HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); + updateStatus = HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_isVendorIDUpdated; + LOGINFO("updateStatus %d\n",updateStatus); + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(msg.vendorId); + if (!updateStatus) + HdmiCecSinkImplementation::_instance->sendDeviceUpdateInfo(header.from.toInt()); + } + void HdmiCecSinkProcessor::process (const GiveDevicePowerStatus &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: GiveDevicePowerStatus sending powerState :%d \n",powerState); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + try + { + conn.sendTo(header.from, MessageEncoder().encode(ReportPowerStatus(PowerStatus(powerState)))); + } + catch(...) + { + LOGWARN("Exception while sending ReportPowerStatus"); + } + } + void HdmiCecSinkProcessor::process (const ReportPowerStatus &msg, const Header &header) + { + uint32_t oldPowerStatus,newPowerStatus; + printHeader(header); + LOGINFO("Command: ReportPowerStatus Power Status from:%s status : %s \n",header.from.toString().c_str(),msg.status.toString().c_str()); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + oldPowerStatus = HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_powerStatus.toInt(); + HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(msg.status); + newPowerStatus = HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_powerStatus.toInt(); + LOGINFO(" oldPowerStatus %d newpower status %d \n",oldPowerStatus,newPowerStatus); + if ((oldPowerStatus != newPowerStatus) ) + { + HdmiCecSinkImplementation::_instance->sendDeviceUpdateInfo(header.from.toInt()); + } + + if((header.from.toInt() == LogicalAddress::AUDIO_SYSTEM) && (HdmiCecSinkImplementation::_instance->m_audioDevicePowerStatusRequested)) { + HdmiCecSinkImplementation::_instance->reportAudioDevicePowerStatusInfo(header.from.toInt(), newPowerStatus); + } + + } + void HdmiCecSinkProcessor::process (const FeatureAbort &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: FeatureAbort opcode=%s, Reason = %s\n", msg.feature.toString().c_str(), msg.reason.toString().c_str()); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + + if(header.from.toInt() < LogicalAddress::UNREGISTERED && + msg.reason.toInt() == AbortReason::UNRECOGNIZED_OPCODE) + { + switch(msg.feature.opCode()) + { + case GET_CEC_VERSION : + { + /* If we get a Feature abort for CEC Version then default to 1.4b */ + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(Version(Version::V_1_4)); + } + break; + case GIVE_DEVICE_VENDOR_ID : + { + /* If we get a Feature abort for CEC Version then default to 1.4b */ + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(VendorID((uint8_t *)"FA", 2)); + } + break; + + case GIVE_OSD_NAME : + { + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(OSDName("")); + } + break; + + case GIVE_DEVICE_POWER_STATUS : + { + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].update(PowerStatus(PowerStatus::POWER_STATUS_FEATURE_ABORT)); + } + break; + } + + HdmiCecSinkImplementation::_instance->deviceList[header.from.toInt()].m_featureAborts.push_back(msg); + } + + LogicalAddress logicaladdress = header.from.toInt(); + OpCode featureOpcode = msg.feature; + AbortReason abortReason = msg.reason; + + HdmiCecSinkImplementation::_instance->reportFeatureAbortEvent(logicaladdress,featureOpcode,abortReason); + + if(msg.feature.opCode() == REQUEST_SHORT_AUDIO_DESCRIPTOR) + { + JsonArray audiodescriptor; + audiodescriptor.Add(0); + HdmiCecSinkImplementation::_instance->Send_ShortAudioDescriptor_Event(audiodescriptor); + } + + } + void HdmiCecSinkProcessor::process (const Abort &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: Abort\n"); + if (!(header.to == LogicalAddress(LogicalAddress::BROADCAST))) + { + AbortReason reason = AbortReason::UNRECOGNIZED_OPCODE; + LogicalAddress logicaladdress =header.from.toInt(); + OpCode feature = msg.opCode(); + HdmiCecSinkImplementation::_instance->sendFeatureAbort(logicaladdress, feature,reason); + } + else + { + LOGINFO("Command: Abort broadcast msg so ignore\n"); + } + } + void HdmiCecSinkProcessor::process (const Polling &msg, const Header &header) { + printHeader(header); + LOGINFO("Command: Polling\n"); + } + + void HdmiCecSinkProcessor::process (const InitiateArc &msg, const Header &header) + { + printHeader(header); + if((!(header.from.toInt() == 0x5)) || (header.to.toInt() == LogicalAddress::BROADCAST)){ + LOGINFO("Ignoring the message coming from addresses other than 0X5 or a braodcast message"); + return; + } + PhysicalAddress physical_addr_invalid = {0x0F,0x0F,0x0F,0x0F}; + PhysicalAddress physical_addr_arc_port = {0x0F,0x0F,0x0F,0x0F}; + + LOGINFO("Command: INITIATE_ARC \n"); + if(!HdmiCecSinkImplementation::_instance || HdmiArcPortID == -1) + return; + + if (HdmiArcPortID == 0 ) + physical_addr_arc_port = {0x01,0x00,0x00,0x00}; + if (HdmiArcPortID == 1 ) + physical_addr_arc_port = {0x02,0x00,0x00,0x00}; + if (HdmiArcPortID == 2 ) + physical_addr_arc_port = {0x03,0x00,0x00,0x00}; + + if( (HdmiCecSinkImplementation::_instance->deviceList[0x5].m_physicalAddr.toString() == physical_addr_arc_port.toString()) || (HdmiCecSinkImplementation::_instance->deviceList[0x5].m_physicalAddr.toString() == physical_addr_invalid.toString()) ) { + LOGINFO("Command: INITIATE_ARC InitiateArc success %s \n",HdmiCecSinkImplementation::_instance->deviceList[0x5].m_physicalAddr.toString().c_str()); + HdmiCecSinkImplementation::_instance->Process_InitiateArc(); + } else { + LOGINFO("Command: INITIATE_ARC InitiateArc ignore %s \n",HdmiCecSinkImplementation::_instance->deviceList[0x5].m_physicalAddr.toString().c_str()); + } + } + void HdmiCecSinkProcessor::process (const TerminateArc &msg, const Header &header) + { + printHeader(header); + if((!(header.from.toInt() == 0x5)) || (header.to.toInt() == LogicalAddress::BROADCAST)){ + LOGINFO("Ignoring the message coming from addresses other than 0X5 or a braodcast message"); + return; + } + if(!HdmiCecSinkImplementation::_instance) + return; + HdmiCecSinkImplementation::_instance->Process_TerminateArc(); + } + void HdmiCecSinkProcessor::process (const ReportShortAudioDescriptor &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: ReportShortAudioDescriptor %s : %d \n",GetOpName(msg.opCode()),numberofdescriptor); + HdmiCecSinkImplementation::_instance->Process_ShortAudioDescriptor_msg(msg); + } + + void HdmiCecSinkProcessor::process (const SetSystemAudioMode &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: SetSystemAudioMode %s audio status %d audio status is %s \n",GetOpName(msg.opCode()),msg.status.toInt(),msg.status.toString().c_str()); + HdmiCecSinkImplementation::_instance->Process_SetSystemAudioMode_msg(msg); + } + void HdmiCecSinkProcessor::process (const ReportAudioStatus &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n",GetOpName(msg.opCode()),msg.status.getAudioMuteStatus(),msg.status.toString().c_str(),msg.status.getAudioVolume()); + if(header.to.toInt() == LogicalAddress::BROADCAST){ + LOGINFO("Ignore Broadcast messages, accepts only direct messages"); + return; + } + HdmiCecSinkImplementation::_instance->Process_ReportAudioStatus_msg(msg); + } + void HdmiCecSinkProcessor::process (const GiveFeatures &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: GiveFeatures \n"); + try + { + if(cecVersion == 2.0) { + conn.sendToAsync(LogicalAddress(LogicalAddress::BROADCAST),MessageEncoder().encode(ReportFeatures(Version::V_2_0,allDevicetype,rcProfile,deviceFeatures))); + } + } + catch(...) + { + LOGWARN("Exception while sending ReportFeatures"); + } + } + void HdmiCecSinkProcessor::process (const RequestCurrentLatency &msg, const Header &header) + { + printHeader(header); + LOGINFO("Command: Request Current Latency :%s, physical address: %s",GetOpName(msg.opCode()),msg.physicaladdress.toString().c_str()); + + if(msg.physicaladdress.toString() == physical_addr.toString()) { + HdmiCecSinkImplementation::_instance->setLatencyInfo(); + } + else { + LOGINFO("Physical Address does not match with TV's physical address"); + return; + } + } +//=========================================== HdmiCecSink ========================================= + + HdmiCecSinkImplementation::HdmiCecSink() + : PluginHost::JSONRPC() + , _pwrMgrNotification(*this) + , _registeredEventHandlers(false) + { + LOGWARN("Initlaizing HdmiCecSink"); + } + + HdmiCecSinkImplementation::~HdmiCecSink() + { + if(_powerManagerPlugin) + { + _powerManagerPlugin.Reset(); + } + _registeredEventHandlers = false; + + profileType = searchRdkProfile(); + + if (profileType == STB || profileType == NOT_FOUND) + { + LOGINFO("Invalid profile type for TV \n"); + return ; + } + + CECDisable(); + m_currentArcRoutingState = ARC_STATE_ARC_EXIT; + + m_semSignaltoArcRoutingThread.release(); + + try + { + if (m_arcRoutingThread.joinable()) + m_arcRoutingThread.join(); + } + catch(const std::system_error& e) + { + LOGERR("system_error exception in thread join %s", e.what()); + } + catch(const std::exception& e) + { + LOGERR("exception in thread join %s", e.what()); + } + + { + m_sendKeyEventThreadExit = true; + std::unique_lock lk(m_sendKeyEventMutex); + m_sendKeyEventThreadRun = true; + m_sendKeyCV.notify_one(); + } + + try + { + if (m_sendKeyEventThread.joinable()) + m_sendKeyEventThread.join(); + } + catch(const std::system_error& e) + { + LOGERR("system_error exception in thread join %s", e.what()); + } + catch(const std::exception& e) + { + LOGERR("exception in thread join %s", e.what()); + } + + HdmiCecSinkImplementation::_instance = nullptr; + DeinitializeIARM(); + } + const std::string HdmiCecSinkImplementation::Configure(PluginHost::IShell *service) + { + InitializePowerManager(service); + profileType = searchRdkProfile(); + + if (profileType == STB || profileType == NOT_FOUND) + { + LOGINFO("Invalid profile type for TV \n"); + return (std::string("Not supported")); + } + + HdmiCecSinkImplementation::_instance = this; + smConnection=NULL; + cecEnableStatus = false; + HdmiCecSinkImplementation::_instance->m_numberOfDevices = 0; + m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; + m_currentActiveSource = -1; + m_isHdmiInConnected = false; + hdmiCecAudioDeviceConnected = false; + m_audioDevicePowerStatusRequested = false; + m_pollNextState = POLL_THREAD_STATE_NONE; + m_pollThreadState = POLL_THREAD_STATE_NONE; + m_video_latency = DEFAULT_VIDEO_LATENCY; + m_latency_flags = DEFAULT_LATENCY_FLAGS ; + m_audio_output_delay = DEFAULT_AUDIO_OUTPUT_DELAY; + + logicalAddressDeviceType = "None"; + logicalAddress = 0xFF; + m_sendKeyEventThreadExit = false; + m_sendKeyEventThread = std::thread(threadSendKeyEvent); + + m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + m_semSignaltoArcRoutingThread.acquire(); + m_arcRoutingThread = std::thread(threadArcRouting); + + + m_arcStartStopTimer.connect( std::bind( &HdmiCecSinkImplementation::arcStartStopTimerFunction, this ) ); + m_arcStartStopTimer.setSingleShot(true); + // load persistence setting + loadSettings(); + + int err; + dsHdmiInGetNumberOfInputsParam_t hdmiInput; + InitializeIARM(); + // get power state: + uint32_t res = Core::ERROR_GENERAL; + PowerState pwrStateCur = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; + PowerState pwrStatePrev = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; + + ASSERT (_powerManagerPlugin); + if (_powerManagerPlugin) { + res = _powerManagerPlugin->GetPowerState(pwrStateCur, pwrStatePrev); + if (Core::ERROR_NONE == res) { + powerState = (pwrStateCur == WPEFramework::Exchange::IPowerManager::POWER_STATE_ON) ? DEVICE_POWER_STATE_ON : DEVICE_POWER_STATE_OFF; + LOGINFO("Current state is PowerManagerPlugin: (%d) powerState :%d \n", pwrStateCur, powerState); + } + } + + err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_API_dsHdmiInGetNumberOfInputs, + (void *)&hdmiInput, + sizeof(hdmiInput)); + + if (err == IARM_RESULT_SUCCESS && hdmiInput.result == dsERR_NONE) + { + LOGINFO("Number of Inputs [%d] \n", hdmiInput.numHdmiInputs ); + m_numofHdmiInput = hdmiInput.numHdmiInputs; + }else{ + LOGINFO("Not able to get Numebr of inputs so defaulting to 3 \n"); + m_numofHdmiInput = 3; + } + + LOGINFO("initalize inputs \n"); + + for (int i = 0; i < m_numofHdmiInput; i++){ + HdmiPortMap hdmiPort((uint8_t)i); + LOGINFO(" Add to vector [%d] \n", i); + hdmiInputs.push_back(hdmiPort); + } + + LOGINFO("Check the HDMI State \n"); + + CheckHdmiInState(); + if (cecSettingEnabled) + { + try + { + CECEnable(); + } + catch(...) + { + LOGWARN("Exception while enabling CEC settings .\r\n"); + } + } + getCecVersion(); + getHdmiArcPortID(); + return (std::string()); + + } + + uint32_t HdmiCecSinkImplementation::Register(Exchange::IHdmiCecSink::INotification* notification) + { + LOGINFO("Register"); + if(notification != nullptr){ + _adminLock.Lock(); + if(std::find(_hdmiCecSinkNotifications.begin(), _hdmiCecSinkNotifications.end(), notification) == _hdmiCecSinkNotifications.end()) + { + _hdmiCecSinkNotifications.push_back(notification); + notification->AddRef(); + } + else + { + LOGERR("Same notification is registered already"); + } + _adminLock.Unlock(); + } + + return Core::ERROR_NONE; + } + + uint32_t HdmiCecSourceImplementation::Unregister(Exchange::IHdmiCecSink::INotification* notification) + { + LOGINFO("Unregister"); + if(notification != nullptr){ + _adminLock.Lock(); + std::list::iterator index = std::find(_hdmiCecSinkNotifications.begin(), _hdmiCecSinkNotifications.end(), notification); + if(index != _hdmiCecSinkNotifications.end()) + { + (*index)->Release(); + _hdmiCecSinkNotifications.erase(index); + } + else + { + LOGERR("Notification is not registered"); + } + _adminLock.Unlock(); + } + + return Core::ERROR_NONE; + } + + + const void HdmiCecSinkImplementation::InitializeIARM() + { + if (Utils::IARM::init()) + { + IARM_Result_t res; + IARM_CHECK( IARM_Bus_RegisterEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG, dsHdmiEventHandler) ); + } + } + + void HdmiCecSinkImplementation::DeinitializeIARM() + { + if (Utils::IARM::isConnected()) + { + IARM_Result_t res; + IARM_CHECK( IARM_Bus_RemoveEventHandler(IARM_BUS_DSMGR_NAME,IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG, dsHdmiEventHandler) ); + } + } + + void HdmiCecSinkImplementation::InitializePowerManager(PluginHost::IShell *service) + { + _powerManagerPlugin = PowerManagerInterfaceBuilder(_T("org.rdk.PowerManager")) + .withIShell(service) + .withRetryIntervalMS(200) + .withRetryCount(25) + .createInterface(); + registerEventHandlers(); + } + void HdmiCecSinkImplementation::registerEventHandlers() + { + ASSERT (_powerManagerPlugin); + + if(!_registeredEventHandlers && _powerManagerPlugin) { + _registeredEventHandlers = true; + _powerManagerPlugin->Register(_pwrMgrNotification.baseInterface()); + } + } + + void HdmiCecSinkImplementation::dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + if (IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG == eventId) + { + IARM_Bus_DSMgr_EventData_t *eventData = (IARM_Bus_DSMgr_EventData_t *)data; + bool isHdmiConnected = eventData->data.hdmi_in_connect.isPortConnected; + dsHdmiInPort_t portId = eventData->data.hdmi_in_connect.port; + LOGINFO("Received IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG event port: %d data:%d \r\n",portId, isHdmiConnected); + HdmiCecSinkImplementation::_instance->onHdmiHotPlug(portId,isHdmiConnected); + } + } + + void HdmiCecSinkImplementation::onPowerModeChanged(const PowerState ¤tState, const PowerState &newState) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + LOGINFO("Event IARM_BUS_PWRMGR_EVENT_MODECHANGED: State Changed %d -- > %d\r", + currentState, newState); + LOGWARN(" m_logicalAddressAllocated 0x%x CEC enable status %d \n",_instance->m_logicalAddressAllocated,_instance->cecEnableStatus); + if(newState == WPEFramework::Exchange::IPowerManager::POWER_STATE_ON) + { + powerState = DEVICE_POWER_STATE_ON; + } + else + { + powerState = DEVICE_POWER_STATE_OFF; + if((_instance->m_currentArcRoutingState == ARC_STATE_REQUEST_ARC_INITIATION) || (_instance->m_currentArcRoutingState == ARC_STATE_ARC_INITIATED)) + { + LOGINFO("%s: Stop ARC \n",__FUNCTION__); + _instance->stopArc(); + } + + } + if (_instance->cecEnableStatus) + { + if ( _instance->m_logicalAddressAllocated != LogicalAddress::UNREGISTERED ) + { + _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus = PowerStatus(powerState); + + if ( powerState != DEVICE_POWER_STATE_ON ) + { + /* reset the current active source when TV on going to standby */ + HdmiCecSinkImplementation::_instance->m_currentActiveSource = -1; + } + /* Initiate a ping straight away */ + HdmiCecSinkImplementation::_instance->m_pollNextState = POLL_THREAD_STATE_PING; + HdmiCecSinkImplementation::_instance->m_ThreadExitCV.notify_one(); + } + } + else + { + LOGWARN("CEC not Enabled\n"); + } + } + + + void HdmiCecSinkImplementation::sendStandbyMessage() + { + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(HdmiCecSinkImplementation::_instance->smConnection)) + return; + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ + LOGERR("Logical Address NOT Allocated Or its not valid"); + return; + } + + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(Standby()), 1000); + } + + void HdmiCecSinkImplementation::onHdmiHotPlug(int portId , int connectStatus) + { + LOGINFO("onHdmiHotPlug Status : %d ", connectStatus); + if(!connectStatus) + { + LOGINFO(" removeDevice port: %d Logical address :%d \r\n",portId,hdmiInputs[portId].m_logicalAddr.toInt() ); + _instance->removeDevice(hdmiInputs[portId].m_logicalAddr.toInt()); + } + CheckHdmiInState(); + + if(cecEnableStatus) { + LOGINFO("cecEnableStatus : %d Trigger CEC Ping !!! \n", cecEnableStatus); + m_pollNextState = POLL_THREAD_STATE_PING; + m_ThreadExitCV.notify_one(); + } + if( HdmiArcPortID >= 0 ) { + updateArcState(); + } + return; + } + void HdmiCecSinkImplementation::updateArcState() + { + if ( m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED ) + { + if (!(hdmiInputs[HdmiArcPortID].m_isConnected)) + { + std::lock_guard lock(_instance->m_arcRoutingStateMutex); + m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + } + else + { + LOGINFO("updateArcState :not updating ARC state current arc state %d ",m_currentArcRoutingState); + } + } + } + void HdmiCecSinkImplementation::arcStartStopTimerFunction() + { + JsonObject params; + + if (m_arcstarting) + { + LOGINFO("arcStartStopTimerFunction ARC start timer expired"); + LOGINFO("notify_device setting that Initiate ARC failed to get the ARC_STATE_ARC_INITIATED state\n"); + params["status"] = string("failure"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ArcInitiationEvent("failure"); + index++; + } + } + else + { + LOGINFO("arcStartStopTimerFunction ARC stop timer expired"); + LOGINFO("notify_device setting that Terminate ARC failed to get the ARC_STATE_ARC_TERMINATED state\n"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ArcTerminationEvent("failure"); + index++; + } + } + /* bring the state machine to the clean state for a new start */ + std::lock_guard lock(_instance->m_arcRoutingStateMutex); + m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + } + void HdmiCecSinkImplementation::Send_ShortAudioDescriptor_Event(JsonArray audiodescriptor) + { + + LOGINFO("Notify the DS "); + std::vector shortAudioDescriptors; + for (size_t i = 0; i < audiodescriptor.Length(); i++) { + shortAudioDescriptors.push_back(audiodescriptor[i].Number()); + } + + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ShortAudioDescriptorEvent(shortAudioDescriptors); + index++; + } + } + + void HdmiCecSinkImplementation::Process_ShortAudioDescriptor_msg(const ReportShortAudioDescriptor &msg) + { + uint8_t numberofdescriptor = msg.numberofdescriptor; + uint32_t descriptor =0; + JsonArray audiodescriptor; + + if (numberofdescriptor) + { + for( uint8_t i=0; i < numberofdescriptor; i++) + { + descriptor = msg.shortAudioDescriptor[i].getAudiodescriptor(); + + LOGINFO("descriptor%d 0x%x\n",i,descriptor); + audiodescriptor.Add(descriptor); + + } + } + else + { + audiodescriptor.Add(descriptor); + } + HdmiCecSinkImplementation::_instance->Send_ShortAudioDescriptor_Event(audiodescriptor); + } + + void HdmiCecSinkImplementation::updateCurrentLatency(int videoLatency, bool lowLatencyMode,int audioOutputCompensated, int audioOutputDelay = 0) + { + uint8_t latencyFlags = 0; + latencyFlags = ((lowLatencyMode & 0x1) << 2) | (audioOutputCompensated & 0x3); + LOGINFO("Video Latency : %d , Low Latency Mode : %d ,Audio Output Compensated value : %d , Audio Output Delay : %d , Latency Flags: %d ", videoLatency, lowLatencyMode, audioOutputCompensated, audioOutputDelay, latencyFlags); + m_video_latency = (videoLatency/2) + 1; + m_latency_flags = latencyFlags; + m_audio_output_delay = (audioOutputDelay/2) + 1; + setLatencyInfo(); + } + + void HdmiCecSinkImplementation::setLatencyInfo() + { + if(!HdmiCecSinkImplementation::_instance) + return; + + if(!(_instance->smConnection)) + return; + + LOGINFO("Send Report Current Latency message \n"); + _instance->smConnection->sendTo(LogicalAddress::BROADCAST,MessageEncoder().encode(ReportCurrentLatency(physical_addr,m_video_latency,m_latency_flags,m_audio_output_delay))); + + } + + void HdmiCecSinkImplementation::Process_SetSystemAudioMode_msg(const SetSystemAudioMode &msg) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + //DD: Check cecSettingEnabled to prevent race conditions which gives immediate UI setting status + //SetSystemAudioMode message may come from AVR/Soundbar while CEC disable is in-progress + if ( cecSettingEnabled != true ) + { + LOGINFO("Process SetSystemAudioMode from Audio device: Cec is disabled-> EnableCEC first"); + return; + } + + if ( (msg.status.toInt() == SYSTEM_AUDIO_MODE_OFF) && (m_currentArcRoutingState == ARC_STATE_ARC_INITIATED)) + { + /* ie system audio mode off -> amplifier goign to standby but still ARC is in initiated state,stop ARC and + bring the ARC state machine to terminated state*/ + LOGINFO("system audio mode off message but arc is not in terminated state so stopping ARC"); + stopArc(); + + } + + if (msg.status.toInt() == SYSTEM_AUDIO_MODE_ON) { + LOGINFO("panel power state is %s", powerState ? "Off" : "On"); + if (powerState == DEVICE_POWER_STATE_ON ) { + LOGINFO("Notifying system audio mode ON event"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->SetSystemAudioModeEvent(msg.status.toString()); + index++; + } + } else { + LOGINFO("Not notifying system audio mode ON event"); + } + } else { + LOGINFO("Notifying system audio Mode OFF event"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->SetSystemAudioModeEvent(msg.status.toString()); + index++; + } + } + } + void HdmiCecSinkImplementation::Process_ReportAudioStatus_msg(const ReportAudioStatus msg) + { + if(!HdmiCecSinkImplementation::_instance) + return; + LOGINFO("Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n",GetOpName(msg.opCode()),msg.status.getAudioMuteStatus(),msg.status.toString().c_str(),msg.status.getAudioVolume()); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ReportAudioStatusEvent(msg.status.getAudioMuteStatus(), msg.status.getAudioVolume()); + index++; + } + + } + void HdmiCecSinkImplementation::sendKeyPressEvent(const int logicalAddress, int keyCode) + { + if(!(_instance->smConnection)) + return; + LOGINFO(" sendKeyPressEvent logicalAddress 0x%x keycode 0x%x\n",logicalAddress,keyCode); + switch(keyCode) + { + case VOLUME_UP: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_VOLUME_UP)),100); + break; + case VOLUME_DOWN: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_VOLUME_DOWN)), 100); + break; + case MUTE: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_MUTE)), 100); + break; + case UP: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_UP)), 100); + break; + case DOWN: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_DOWN)), 100); + break; + case LEFT: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_LEFT)), 100); + break; + case RIGHT: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_RIGHT)), 100); + break; + case SELECT: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_SELECT)), 100); + break; + case HOME: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_HOME)), 100); + break; + case BACK: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_BACK)), 100); + break; + case NUMBER_0: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_0)), 100); + break; + case NUMBER_1: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_1)), 100); + break; + case NUMBER_2: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_2)), 100); + break; + case NUMBER_3: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_3)), 100); + break; + case NUMBER_4: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_4)), 100); + break; + case NUMBER_5: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_5)), 100); + break; + case NUMBER_6: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_6)), 100); + break; + case NUMBER_7: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_7)), 100); + break; + case NUMBER_8: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_8)), 100); + break; + case NUMBER_9: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_9)), 100); + break; + + } + } + + void HdmiCecSinkImplementation::sendUserControlPressed(const int logicalAddress, int keyCode) + { + if(!(_instance->smConnection)) + return; + LOGINFO(" sendUserControlPressed logicalAddress 0x%x keycode 0x%x\n",logicalAddress,keyCode); + switch(keyCode) + { + case VOLUME_UP: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_VOLUME_UP)),100); + break; + case VOLUME_DOWN: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_VOLUME_DOWN)), 100); + break; + case MUTE: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_MUTE)), 100); + break; + case UP: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_UP)), 100); + break; + case DOWN: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_DOWN)), 100); + break; + case LEFT: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_LEFT)), 100); + break; + case RIGHT: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_RIGHT)), 100); + break; + case SELECT: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_SELECT)), 100); + break; + case HOME: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_HOME)), 100); + break; + case BACK: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_BACK)), 100); + break; + case NUMBER_0: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_0)), 100); + break; + case NUMBER_1: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_1)), 100); + break; + case NUMBER_2: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_2)), 100); + break; + case NUMBER_3: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_3)), 100); + break; + case NUMBER_4: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_4)), 100); + break; + case NUMBER_5: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_5)), 100); + break; + case NUMBER_6: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_6)), 100); + break; + case NUMBER_7: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_7)), 100); + break; + case NUMBER_8: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_8)), 100); + break; + case NUMBER_9: + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlPressed(UICommand::UI_COMMAND_NUM_9)), 100); + break; + + } + } + + void HdmiCecSinkImplementation::sendKeyReleaseEvent(const int logicalAddress) + { + if(!(_instance->smConnection)) + return; + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlReleased()), 100); + + } + + void HdmiCecSinkImplementation::sendUserControlReleased(const int logicalAddress) + { + if(!(_instance->smConnection)) + return; + LOGINFO(" User Control Released \n"); + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(UserControlReleased()), 100); + } + + void HdmiCecSinkImplementation::sendDeviceUpdateInfo(const int logicalAddress) + { + LOGINFO("Send Device Update Info \n"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnDeviceInfoUpdated(logicalAddress); + index++; + } + } + void HdmiCecSinkImplementation::systemAudioModeRequest() + { + if ( cecEnableStatus != true ) + { + LOGINFO("systemAudioModeRequest: Cec is disabled-> EnableCEC first"); + return; + } + + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + LOGINFO(" Send systemAudioModeRequest "); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(SystemAudioModeRequest(physical_addr)), 1000); + + } + void HdmiCecSinkImplementation::sendGiveAudioStatusMsg() + { + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + LOGINFO(" Send GiveAudioStatus "); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(GiveAudioStatus()), 100); + + } + void HdmiCecSinkImplementation::reportAudioDevicePowerStatusInfo(const int logicalAddress, const int powerStatus) + { + JsonObject params; + params["powerStatus"] = JsonValue(powerStatus); + LOGINFO("Panle power state is %s", powerState ? "Off" : "On"); + if (powerStatus != AUDIO_DEVICE_POWERSTATE_OFF) { + if (powerState == DEVICE_POWER_STATE_ON ) { + LOGINFO("Notify DS!!! logicalAddress = %d , Audio device power status = %d \n", logicalAddress, powerStatus); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ReportAudioDevicePowerStatus(powerStatus); + index++; + } + } else { + LOGINFO("Not notifying audio device power state to DS"); + } + } else { + LOGINFO("Notify DS!!! logicalAddress = %d , Audio device power status = %d \n", logicalAddress, powerStatus); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ReportAudioDevicePowerStatus(powerStatus); + index++; + } + } + } + + void HdmiCecSinkImplementation::SendStandbyMsgEvent(const int logicalAddress) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->StandbyMessageReceived(logicalAddress); + index++; + } + + } + uint32_t HdmiCecSinkImplementation::SetEnabled(const bool enabled, HdmiCecSinkSuccess &success) + { + LOGINFOMETHOD(); + getBoolParameter("enabled", enabled); + + setEnabled(enabled); + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::GetEnabled(bool &enabled, bool &success) + { + enabled = getEnabled(); + success = true; + } + + uint32_t HdmiCecSinkImplementation::GetAudioDeviceConnectedStatus(bool &connected, bool &success) + { + connected = getAudioDeviceConnectedStatus(); + success = true; + } + + uint32_t HdmiCecSinkImplementation::requestAudioDevicePowerStatusWrapper(const JsonObject& parameters, JsonObject& response) + { + requestAudioDevicePowerStatus(); + returnResponse(true); + } + + uint32_t HdmiCecSinkImplementation::GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) + { + char routeString[1024] = {'\0'}; + int length = 0; + std::stringstream temp; + + if ( HdmiCecSinkImplementation::_instance->m_currentActiveSource != -1 ) + { + int n = HdmiCecSinkImplementation::_instance->m_currentActiveSource; + available = true; + logicalAddress = HdmiCecSinkImplementation::_instance->deviceList[n].m_logicalAddress.toInt(); + physicalAddress = HdmiCecSinkImplementation::_instance->deviceList[n].m_physicalAddr.toString().c_str(); + deviceType = HdmiCecSinkImplementation::_instance->deviceList[n].m_deviceType.toString().c_str(); + cecVersion = HdmiCecSinkImplementation::_instance->deviceList[n].m_cecVersion.toString().c_str(); + osdName = HdmiCecSinkImplementation::_instance->deviceList[n].m_osdName.toString().c_str(); + vendorID = HdmiCecSinkImplementation::_instance->deviceList[n].m_vendorID.toString().c_str(); + powerStatus = HdmiCecSinkImplementation::_instance->deviceList[n].m_powerStatus.toString().c_str(); + + + if ( HdmiCecSinkImplementation::_instance->deviceList[n].m_physicalAddr.getByteValue(0) != 0 ) + { + snprintf(&routeString[length], sizeof(routeString) - length, "%s%d", "HDMI",(HdmiCecSinkImplementation::_instance->deviceList[n].m_physicalAddr.getByteValue(0) - 1)); + } + else if ( HdmiCecSinkImplementation::_instance->deviceList[n].m_physicalAddr.getByteValue(0) == 0 ) + { + snprintf(&routeString[length], sizeof(routeString) - length, "%s", "TV"); + } + + temp << (char *)routeString; + port = temp.str(); + + } + else + { + available = false; + } + + success = true; + + } + + uint32_t HdmiCecSinkImplementation::GetDeviceList(uint32_t &numberofdevices, IHdmiCecSinkDeviceListIterator*& deviceList, bool &success) + { + LOGINFOMETHOD(); + + numberofdevices = HdmiCecSinkImplementation::_instance->m_numberOfDevices; + LOGINFO("getDeviceListWrapper m_numberOfDevices :%d \n", HdmiCecSinkImplementation::_instance->m_numberOfDevices); + std::vector localDevices; + Exchange::IHdmiCecSource::HdmiCecSinkDevices actual_hdmicecdevices = {0}; + + for (int n = 0; n <= LogicalAddress::UNREGISTERED; n++) + { + + if ( n != HdmiCecSinkImplementation::_instance->m_logicalAddressAllocated && + HdmiCecSinkImplementation::_instance->deviceList[n].m_isDevicePresent ) + { + + actual_hdmicecdevices.logicalAddress = HdmiCecSinkImplementation::_instance->deviceList[n].m_logicalAddress.toInt(); + actual_hdmicecdevices.physicalAddress = HdmiCecSinkImplementation::_instance->deviceList[n].m_physicalAddr.toString().c_str(); + actual_hdmicecdevices.deviceType = HdmiCecSinkImplementation::_instance->deviceList[n].m_deviceType.toString().c_str(); + actual_hdmicecdevices.cecVersion = HdmiCecSinkImplementation::_instance->deviceList[n].m_cecVersion.toString().c_str(); + actual_hdmicecdevices.osdName = HdmiCecSinkImplementation::_instance->deviceList[n].m_osdName.toString().c_str(); + actual_hdmicecdevices.vendorID = HdmiCecSinkImplementation::_instance->deviceList[n].m_vendorID.toString().c_str(); + actual_hdmicecdevices.powerStatus = HdmiCecSinkImplementation::_instance->deviceList[n].m_powerStatus.toString().c_str(); + int hdmiPortNumber = -1; + LOGINFO("getDeviceListWrapper m_numofHdmiInput:%d looking for Logical Address :%d \n", m_numofHdmiInput, HdmiCecSinkImplementation::_instance->deviceList[n].m_logicalAddress.toInt()); + for (int i=0; i < m_numofHdmiInput; i++) + { + LOGINFO("getDeviceListWrapper connected : %d, portid:%d LA: %d \n", hdmiInputs[i].m_isConnected, hdmiInputs[i].m_portID, hdmiInputs[i].m_logicalAddr.toInt()); + if(hdmiInputs[i].m_isConnected && hdmiInputs[i].m_logicalAddr.toInt() == HdmiCecSinkImplementation::_instance->deviceList[n].m_logicalAddress.toInt()) + { + hdmiPortNumber = hdmiInputs[i].m_portID; + LOGINFO("got portid :%d break \n", hdmiPortNumber); + break; + } + } + actual_hdmicecdevices.powerStatus = hdmiPortNumber; + localDevices.push_back(actual_hdmicecdevices); + } + } + + deviceList = new HdmiCecSinkDeviceListIterator(localDevices); + success = true; + } + + + uint32_t HdmiCecSinkImplementation::SetOSDName(const string &name, HdmiCecSinkSuccess &success) + { + LOGINFOMETHOD(); + + LOGINFO("SetOSDName osdName: %s",name.c_str()); + osdName = name.c_str(); + Utils::persistJsonSettings (CEC_SETTING_ENABLED_FILE, CEC_SETTING_OSD_NAME, JsonValue(name.c_str())); + + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::GetOSDName(string &name, bool &success) + { + name = osdName.toString(); + LOGINFO("GetOSDName osdName : %s \n",osdName.toString().c_str()); + success = true; + } + + uint32_t HdmiCecSinkImplementation::PrintDeviceList(bool &printed, bool &success) + { + printDeviceList(); + printed = true; + success = true; + } + + uint32_t HdmiCecSinkImplementation::SetActiveSource(HdmiCecSinkSuccess &success) + { + setActiveSource(false); + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) + { + + std::string id = activePath.String(); + PhysicalAddress phy_addr = PhysicalAddress(id); + LOGINFO("Addr = %s, length = %zu", id.c_str(), id.length()); + setStreamPath(phy_addr); + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute, bool &success) + { + std::vector route; + char routeString[1024] = {'\0'}; + int length = 0; + std::vector paths; + std::stringstream temp; + + if (HdmiCecSinkImplementation::_instance->m_currentActiveSource != -1 && + HdmiCecSinkImplementation::_instance->m_currentActiveSource != HdmiCecSinkImplementation::_instance->m_logicalAddressAllocated ) + { + HdmiCecSinkImplementation::_instance->getActiveRoute(LogicalAddress(HdmiCecSinkImplementation::_instance->m_currentActiveSource), route); + + if (route.size()) + { + available = true; + length = route.size(); + + for (unsigned int i=0; i < route.size(); i++) + { + if ( route[i] != LogicalAddress::UNREGISTERED ) + { + Exchange::IHdmiCecSink::HdmiCecSinkActivePath device; + + device.logicalAddress = HdmiCecSinkImplementation::_instance->deviceList[route[i]].m_logicalAddress.toInt(); + device.physicalAddress = HdmiCecSinkImplementation::_instance->deviceList[route[i]].m_physicalAddr.toString().c_str(); + device.deviceType = HdmiCecSinkImplementation::_instance->deviceList[route[i]].m_deviceType.toString().c_str(); + device.vendorID = HdmiCecSinkImplementation::_instance->deviceList[route[i]].m_osdName.toString().c_str(); + device.osdName = HdmiCecSinkImplementation::_instance->deviceList[route[i]].m_vendorID.toString().c_str(); + + paths.push_back(device); + + snprintf(&routeString[length], sizeof(routeString) - length, "%s", _instance->deviceList[route[i]].m_logicalAddress.toString().c_str()); + length += _instance->deviceList[route[i]].m_logicalAddress.toString().length(); + snprintf(&routeString[length], sizeof(routeString) - length, "(%s", _instance->deviceList[route[i]].m_osdName.toString().c_str()); + length += _instance->deviceList[route[i]].m_osdName.toString().length(); + snprintf(&routeString[length], sizeof(routeString) - length, "%s", ")-->"); + length += strlen(")-->"); + if( i + 1 == route.size() ) + { + snprintf(&routeString[length], sizeof(routeString) - length, "%s%d", "HDMI",(HdmiCecSinkImplementation::_instance->deviceList[route[i]].m_physicalAddr.getByteValue(0) - 1)); + } + } + } + + pathList = new HdmiCecSinkActivePathIterator(paths); + temp << (char *)routeString; + ActiveRoute = temp.str(); + LOGINFO("ActiveRoute = [%s]", routeString); + } + else{ + available = false; + } + + } + else if ( HdmiCecSinkImplementation::_instance->m_currentActiveSource == HdmiCecSinkImplementation::_instance->m_logicalAddressAllocated ) + { + available = true; + ActiveRoute = "TV"; + } + else + { + available = false; + } + + success = true; + } + + uint32_t HdmiCecSinkImplementation::RequestActiveSource(HdmiCecSinkSuccess &success) + { + requestActiveSource(); + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::SetRoutingChange(const string &oldPort, const string &newPort, HdmiCecSinkSuccess &success) + { + if ((oldPort.find("HDMI",0) != std::string::npos || + oldPort.find("TV",0) != std::string::npos ) && + (newPort.find("HDMI", 0) != std::string::npos || + newPort.find("TV", 0) != std::string::npos )) + { + setRoutingChange(oldPort, newPort); + success.success = true; + } + else + { + success.success = false; + } + } + + + uint32_t HdmiCecSinkImplementation::setMenuLanguageWrapper(const JsonObject& parameters, JsonObject& response) + { + std::string lang; + + returnIfParamNotFound(parameters, "language"); + + lang = parameters["language"].String(); + + setCurrentLanguage(Language(lang.data())); + sendMenuLanguage(); + returnResponse(true); + } + + + uint32_t HdmiCecSinkImplementation::SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) + { + LOGINFOMETHOD(); + + unsigned int vendorID = 0x00; + try + { + vendorID = stoi(vendorId,NULL,16); + } + catch (...) + { + LOGWARN("Exception in setVendorIdWrapper set default value\n"); + vendorID = 0x0019FB; + } + appVendorId = {(uint8_t)(vendorID >> 16 & 0xff),(uint8_t)(vendorID>> 8 & 0xff),(uint8_t) (vendorID & 0xff)}; + LOGINFO("appVendorId : %s vendorID :%x \n",appVendorId.toString().c_str(), vendorID ); + Utils::persistJsonSettings (CEC_SETTING_ENABLED_FILE, CEC_SETTING_VENDOR_ID, JsonValue(vendorID)); + + success.success = true; + } + uint32_t HdmiCecSinkImplementation::SetupARCRouting(const bool enabled, HdmiCecSinkSuccess &success) + { + if(enabled) + { + startArc(); + } + else + { + stopArc(); + } + + success.success = true; + } + uint32_t HdmiCecSinkImplementation::GetVendorId(string &vendorid, bool &success) + { + LOGINFO("GetVendorId appVendorId : %s \n",appVendorId.toString().c_str()); + vendorid = appVendorId.toString() ; + success = true; + } + + uint32_t HdmiCecSinkImplementation::RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) + { + requestShortaudioDescriptor(); + success.success = true; + } + uint32_t HdmiCecSinkImplementation::SendStandbyMessage(HdmiCecSinkSuccess &success) + { + sendStandbyMessage(); + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) + { + LOGINFO("%s invoked. \n",__FUNCTION__); + systemAudioModeRequest(); + success.success = true; + } + uint32_t HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) + { + string logicalAddress = logicalAddress.String(); + string keyCode = keyCode.String(); + SendKeyInfo keyInfo; + keyInfo.logicalAddr = stoi(logicalAddress); + keyInfo.keyCode = stoi(keyCode); + keyInfo.UserControl = "sendKeyPressEvent"; + std::unique_lock lk(m_sendKeyEventMutex); + m_SendKeyQueue.push(keyInfo); + m_sendKeyEventThreadRun = true; + m_sendKeyCV.notify_one(); + LOGINFO("Post send key press event to queue size:%zu \n",m_SendKeyQueue.size()); + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) + { + string logicalAddress = logicalAddress.String(); + string keyCode = keyCode.String(); + SendKeyInfo keyInfo; + keyInfo.logicalAddr = stoi(logicalAddress); + keyInfo.keyCode = stoi(keyCode); + keyInfo.UserControl = "sendUserControlPressed"; + std::unique_lock lk(m_sendKeyEventMutex); + m_SendKeyQueue.push(keyInfo); + m_sendKeyEventThreadRun = true; + m_sendKeyCV.notify_one(); + LOGINFO("User control pressed, queue size:%zu \n",m_SendKeyQueue.size()); + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) + { + string logicalAddress = logicalAddress.String(); + SendKeyInfo keyInfo; + keyInfo.logicalAddr = stoi(logicalAddress); + keyInfo.keyCode = 0; + keyInfo.UserControl = "sendUserControlReleased"; + std::unique_lock lk(m_sendKeyEventMutex); + m_SendKeyQueue.push(keyInfo); + m_sendKeyEventThreadRun = true; + m_sendKeyCV.notify_one(); + LOGINFO("User Control Released, queue size:%zu \n",m_SendKeyQueue.size()); + success.success = true; + } + + uint32_t HdmiCecSinkImplementation::SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) + { + sendGiveAudioStatusMsg(); + success.success = true; + } + uint32_t HdmiCecSinkImplementation::SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) + { + int video_latency,audio_output_compensated,audio_output_delay; + bool low_latency_mode; + + LOGINFO("SetLatencyInfo videoLatency : %s lowLatencyMode : %s audioOutputCompensated : %s audioOutputDelay : %s \n",videoLatency.c_str(),lowLatencyMode.c_str(),audioOutputCompensated.c_str(),audioOutputDelay.c_str()); + video_latency = stoi(videoLatency); + low_latency_mode = stoi(lowLatencyMode); + audio_output_compensated = stoi(audioOutputCompensated); + audio_output_delay = stoi(audioOutputDelay); + + updateCurrentLatency(video_latency, low_latency_mode,audio_output_compensated, audio_output_delay); + success.success = true; + } + bool HdmiCecSinkImplementation::loadSettings() + { + Core::File file; + file = CEC_SETTING_ENABLED_FILE; + + if( file.Open()) + { + JsonObject parameters; + parameters.IElement::FromFile(file); + bool isConfigAdded = false; + + if( parameters.HasLabel(CEC_SETTING_ENABLED)) + { + getBoolParameter(CEC_SETTING_ENABLED, cecSettingEnabled); + LOGINFO("CEC_SETTING_ENABLED present value:%d",cecSettingEnabled); + } + else + { + parameters[CEC_SETTING_ENABLED] = true; + cecSettingEnabled = true; + isConfigAdded = true; + LOGINFO("CEC_SETTING_ENABLED not present set dafult true:\n "); + } + + if( parameters.HasLabel(CEC_SETTING_OTP_ENABLED)) + { + getBoolParameter(CEC_SETTING_OTP_ENABLED, cecOTPSettingEnabled); + LOGINFO("CEC_SETTING_OTP_ENABLED present value :%d",cecOTPSettingEnabled); + } + else + { + parameters[CEC_SETTING_OTP_ENABLED] = true; + cecOTPSettingEnabled = true; + isConfigAdded = true; + LOGINFO("CEC_SETTING_OTP_ENABLED not present set dafult true:\n "); + } + if( parameters.HasLabel(CEC_SETTING_OSD_NAME)) + { + std::string osd_name; + getStringParameter(CEC_SETTING_OSD_NAME, osd_name); + osdName = osd_name.c_str(); + LOGINFO("CEC_SETTING_OSD_NAME present osd_name :%s",osdName.toString().c_str()); + } + else + { + parameters[CEC_SETTING_OSD_NAME] = osdName.toString(); + LOGINFO("CEC_SETTING_OSD_NMAE not present set dafult value :%s\n ",osdName.toString().c_str()); + isConfigAdded = true; + } + unsigned int vendorId = (defaultVendorId.at(0) <<16) | ( defaultVendorId.at(1) << 8 ) | defaultVendorId.at(2); + if( parameters.HasLabel(CEC_SETTING_VENDOR_ID)) + { + getNumberParameter(CEC_SETTING_VENDOR_ID, vendorId); + LOGINFO("CEC_SETTING_VENDOR_ID present :%x ",vendorId); + } + else + { + LOGINFO("CEC_SETTING_VENDOR_ID not present set dafult value :%x \n ",vendorId); + parameters[CEC_SETTING_VENDOR_ID] = vendorId; + isConfigAdded = true; + } + + appVendorId = {(uint8_t)(vendorId >> 16 & 0xff),(uint8_t)(vendorId >> 8 & 0xff),(uint8_t) (vendorId & 0xff)}; + LOGINFO("appVendorId : %s vendorId :%x \n",appVendorId.toString().c_str(), vendorId ); + + if(isConfigAdded) + { + LOGINFO("isConfigAdded true so update file:\n "); + file.Destroy(); + file.Create(); + parameters.IElement::ToFile(file); + + } + + file.Close(); + } + else + { + LOGINFO("CEC_SETTING_ENABLED_FILE file not present create with default settings "); + file.Open(false); + if (!file.IsOpen()) + file.Create(); + + JsonObject parameters; + unsigned int vendorId = (defaultVendorId.at(0) <<16) | ( defaultVendorId.at(1) << 8 ) | defaultVendorId.at(2); + parameters[CEC_SETTING_ENABLED] = true; + parameters[CEC_SETTING_OSD_NAME] = osdName.toString(); + parameters[CEC_SETTING_VENDOR_ID] = vendorId; + + cecSettingEnabled = true; + cecOTPSettingEnabled = true; + parameters.IElement::ToFile(file); + + file.Close(); + + } + + return cecSettingEnabled; + } + + void HdmiCecSinkImplementation::setEnabled(bool enabled) + { + LOGINFO("Entered setEnabled: %d cecSettingEnabled :%d ",enabled, cecSettingEnabled); + + if (cecSettingEnabled != enabled) + { + Utils::persistJsonSettings (CEC_SETTING_ENABLED_FILE, CEC_SETTING_ENABLED, JsonValue(enabled)); + cecSettingEnabled = enabled; + } + if(true == enabled) + { + CECEnable(); + } + else + { + CECDisable(); + } + return; + } + + void HdmiCecSinkImplementation::updateImageViewOn(const int logicalAddress) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || + logicalAddress == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if (_instance->deviceList[logicalAddress].m_isDevicePresent && + _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) + { + /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnWakeupFromStandby(logicalAddress); + index++; + } + } + + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnInActiveSource(logicalAddress); + index++; + } + } + + void HdmiCecSinkImplementation::updateTextViewOn(const int logicalAddress) + { + JsonObject params; + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || + logicalAddress == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if (_instance->deviceList[logicalAddress].m_isDevicePresent && + _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) + { + /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnWakeupFromStandby(logicalAddress); + index++; + } + } + + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnTextViewOnMsg(logicalAddress); + index++; + } + } + + + void HdmiCecSinkImplementation::updateDeviceChain(const LogicalAddress &logicalAddress, const PhysicalAddress &phy_addr) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if (_instance->deviceList[logicalAddress.toInt()].m_isDevicePresent && + logicalAddress.toInt() != _instance->m_logicalAddressAllocated) + { + for (int i=0; i < m_numofHdmiInput; i++) + { + LOGINFO(" addr = %d, portID = %d", phy_addr.getByteValue(0), hdmiInputs[i].m_portID); + if (phy_addr.getByteValue(0) == (hdmiInputs[i].m_portID + 1)) { + hdmiInputs[i].addChild(logicalAddress, phy_addr); + } + } + } + } + + void HdmiCecSinkImplementation::getActiveRoute(const LogicalAddress &logicalAddress, std::vector &route) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || + logicalAddress.toInt() == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if (_instance->deviceList[logicalAddress.toInt()].m_isDevicePresent && + logicalAddress.toInt() != _instance->m_logicalAddressAllocated && + _instance->deviceList[logicalAddress.toInt()].m_isActiveSource ) + { + route.clear(); + for (int i=0; i < m_numofHdmiInput; i++) + { + LOGINFO("physicalAddress = [%d], portID = %d", _instance->deviceList[logicalAddress.toInt()].m_physicalAddr.getByteValue(0), hdmiInputs[i].m_portID); + if (_instance->deviceList[logicalAddress.toInt()].m_physicalAddr.getByteValue(0) == (hdmiInputs[i].m_portID + 1)) { + hdmiInputs[i].getRoute(_instance->deviceList[logicalAddress.toInt()].m_physicalAddr, route); + } + } + } + else { + LOGERR("Not in correct state to Find Route"); + } + } + + + void HdmiCecSinkImplementation::CheckHdmiInState() + { + int err; + bool isAnyPortConnected = false; + + dsHdmiInGetStatusParam_t params; + err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, + IARM_BUS_DSMGR_API_dsHdmiInGetStatus, + (void *)¶ms, + sizeof(params)); + + if(err == IARM_RESULT_SUCCESS && params.result == dsERR_NONE ) + { + for( int i = 0; i < m_numofHdmiInput; i++ ) + { + LOGINFO("Is HDMI In Port [%d] connected [%d] \n",i, params.status.isPortConnected[i]); + if ( params.status.isPortConnected[i] ) + { + isAnyPortConnected = true; + } + + LOGINFO("update Port Status [%d] \n", i); + hdmiInputs[i].update(params.status.isPortConnected[i]); + } + } + + if ( isAnyPortConnected ) { + m_isHdmiInConnected = true; + } else { + m_isHdmiInConnected = false; + } + } + + void HdmiCecSinkImplementation::requestActiveSource() + { + if(!HdmiCecSinkImplementation::_instance) + return; + + if(!(_instance->smConnection)) + return; + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + _instance->smConnection->sendTo(LogicalAddress::BROADCAST, + MessageEncoder().encode(RequestActiveSource()), 500); + } + + void HdmiCecSinkImplementation::setActiveSource(bool isResponse) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + if(!(_instance->smConnection)) + return; + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if (isResponse && (_instance->m_currentActiveSource != _instance->m_logicalAddressAllocated) ) + { + LOGWARN("TV is not current Active Source"); + return; + } + + _instance->smConnection->sendTo(LogicalAddress::BROADCAST, + MessageEncoder().encode(ActiveSource(_instance->deviceList[_instance->m_logicalAddressAllocated].m_physicalAddr)), 500); + _instance->m_currentActiveSource = _instance->m_logicalAddressAllocated; + } + + void HdmiCecSinkImplementation::setCurrentLanguage(const Language &lang) + { + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage = lang; + } + + void HdmiCecSinkImplementation::sendMenuLanguage() + { + Language lang = ""; + if(!HdmiCecSinkImplementation::_instance) + return; + + if(!(_instance->smConnection)) + return; + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + lang = _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage; + + _instance->smConnection->sendTo(LogicalAddress::BROADCAST, MessageEncoder().encode(SetMenuLanguage(lang)), 100); + } + + void HdmiCecSinkImplementation::updateInActiveSource(const int logical_address, const InActiveSource &source ) + { + JsonObject params; + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if( logical_address != _instance->m_logicalAddressAllocated ) + { + _instance->deviceList[logical_address].m_isActiveSource = false; + + if ( _instance->m_currentActiveSource == logical_address ) + { + _instance->m_currentActiveSource = -1; + } + + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnInActiveSource(logicalAddress, source.physicalAddress.toString()); + index++; + } + } + } + + void HdmiCecSinkImplementation::updateActiveSource(const int logical_address, const ActiveSource &source ) + { + JsonObject params; + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if( logical_address != _instance->m_logicalAddressAllocated ) + { + if ( _instance->m_currentActiveSource != -1 ) + { + _instance->deviceList[_instance->m_currentActiveSource].m_isActiveSource = false; + } + + _instance->deviceList[logical_address].m_isActiveSource = true; + _instance->deviceList[logical_address].update(source.physicalAddress); + _instance->m_currentActiveSource = logical_address; + + if (_instance->deviceList[logical_address].m_isDevicePresent && + _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) + { + /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnWakeupFromStandby(logicalAddress); + index++; + } + } + + string physicalAddress = _instance->deviceList[logical_address].m_physicalAddr.toString().c_str(); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnActiveSourceChange(logicalAddress, physicalAddress); + index++; + } + } + } + + void HdmiCecSinkImplementation::requestShortaudioDescriptor() + { + if ( cecEnableStatus != true ) + { + LOGINFO("requestShortaudioDescriptor: cec is disabled-> EnableCEC first"); + return; + } + + if(!HdmiCecSinkImplementation::_instance) + return; + + if(!(_instance->smConnection)) + return; + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + LOGINFO(" Send requestShortAudioDescriptor Message "); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestShortAudioDescriptor(formatid,audioFormatCode,numberofdescriptor)), 1000); + + } + + void HdmiCecSinkImplementation::requestAudioDevicePowerStatus() + { + if ( cecEnableStatus != true ) + { + LOGWARN("cec is disabled-> EnableCEC first"); + return; + } + + if(!HdmiCecSinkImplementation::_instance) + return; + + if(!(_instance->smConnection)) + return; + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + LOGINFO(" Send GiveDevicePowerStatus Message to Audio system in the network \n"); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM, MessageEncoder().encode(GiveDevicePowerStatus()), 500); + + m_audioDevicePowerStatusRequested = true; + } + + void HdmiCecSinkImplementation::sendFeatureAbort(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason) + { + + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + LOGINFO(" Sending FeatureAbort to %s for opcode %s with reason %s ",logicalAddress.toString().c_str(),feature.toString().c_str(),reason.toString().c_str()); + _instance->smConnection->sendTo(logicalAddress, MessageEncoder().encode(FeatureAbort(feature,reason)), 500); + } + + void HdmiCecSinkImplementation::reportFeatureAbortEvent(const LogicalAddress logicalAddress, const OpCode featureOpcode, const AbortReason abortReason) + { + LOGINFO(" Notifying the UI FeatureAbort from the %s for the opcode %s with the reason %s ",logicalAddress.toString().c_str(),featureOpcode.toString().c_str(),abortReason.toString().c_str()); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ReportFeatureAbortEvent(logicalAddress.toInt(), featureOpcode.opCode(), abortReason.toInt()); + index++; + } + } + + void HdmiCecSinkImplementation::pingDevices(std::vector &connected , std::vector &disconnected) + { + int i; + + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + for(i=0; i< LogicalAddress::UNREGISTERED; i++ ) { + if ( i != _instance->m_logicalAddressAllocated ) + { + //LOGWARN("PING for 0x%x \r\n",i); + try { + _instance->smConnection->ping(LogicalAddress(_instance->m_logicalAddressAllocated), LogicalAddress(i), Throw_e()); + } + catch(CECNoAckException &e) + { + if ( _instance->deviceList[i].m_isDevicePresent ) { + disconnected.push_back(i); + } + //LOGWARN("Ping device: 0x%x caught %s \r\n", i, e.what()); + usleep(50000); + continue; + } + catch(Exception &e) + { + LOGWARN("Ping device: 0x%x caught %s \r\n", i, e.what()); + usleep(50000); + continue; + } + + /* If we get ACK, then the device is present in the network*/ + if ( !_instance->deviceList[i].m_isDevicePresent ) + { + connected.push_back(i); + //LOGWARN("Ping success, added device: 0x%x \r\n", i); + } + usleep(50000); + } + } + } + + int HdmiCecSinkImplementation::requestType( const int logicalAddress ) { + int requestType = CECDeviceParams::REQUEST_NONE; + + if ( !_instance->deviceList[logicalAddress].m_isPAUpdated || !_instance->deviceList[logicalAddress].m_isDeviceTypeUpdated ) { + requestType = CECDeviceParams::REQUEST_PHISICAL_ADDRESS; + }else if ( !_instance->deviceList[logicalAddress].m_isOSDNameUpdated ) { + requestType = CECDeviceParams::REQUEST_OSD_NAME; + }else if ( !_instance->deviceList[logicalAddress].m_isVersionUpdated ) { + requestType = CECDeviceParams::REQUEST_CEC_VERSION; + }else if ( !_instance->deviceList[logicalAddress].m_isVendorIDUpdated ) { + requestType = CECDeviceParams::REQUEST_DEVICE_VENDOR_ID; + }else if ( !_instance->deviceList[logicalAddress].m_isPowerStatusUpdated ) { + requestType = CECDeviceParams::REQUEST_POWER_STATUS; + } + + return requestType; + } + + void HdmiCecSinkImplementation::printDeviceList() { + int i; + + if(!HdmiCecSinkImplementation::_instance) + return; + + for(i=0; i< 16; i++) + { + if (HdmiCecSinkImplementation::_instance->deviceList[i].m_isDevicePresent) { + LOGWARN("------ Device ID = %d--------", i); + HdmiCecSinkImplementation::_instance->deviceList[i].printVariable(); + LOGWARN("-----------------------------"); + } + } + } + + void HdmiCecSinkImplementation::setStreamPath( const PhysicalAddress &physical_addr) { + + if(!HdmiCecSinkImplementation::_instance) + return; + + if(!(_instance->smConnection)) + return; + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ + LOGERR("Logical Address NOT Allocated Or its not valid"); + return; + } + + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(SetStreamPath(physical_addr)), 500); + } + + void HdmiCecSinkImplementation::setRoutingChange(const std::string &from, const std::string &to) { + PhysicalAddress oldPhyAddr = {0xF,0xF,0xF,0xF}; + PhysicalAddress newPhyAddr = {0xF,0xF,0xF,0xF}; + int oldPortID = -1; + int newPortID = -1; + + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ + LOGERR("Logical Address NOT Allocated Or its not valid"); + return; + } + + if( from.find("TV",0) != std::string::npos ) + { + oldPhyAddr = _instance->deviceList[_instance->m_logicalAddressAllocated].m_physicalAddr; + _instance->m_currentActiveSource = -1; + } + else + { + oldPortID = stoi(from.substr(4,1),NULL,16); + if ( oldPortID < _instance->m_numofHdmiInput ) + { + oldPhyAddr = _instance->hdmiInputs[oldPortID].m_physicalAddr; + } + else + { + LOGERR("Invalid HDMI Old Port ID"); + return; + } + } + + if( to.find("TV",0) != std::string::npos ) + { + newPhyAddr = _instance->deviceList[_instance->m_logicalAddressAllocated].m_physicalAddr; + /*set active source as TV */ + _instance->m_currentActiveSource = _instance->m_logicalAddressAllocated; + } + else + { + newPortID = stoi(to.substr(4,1),NULL,16); + + if ( newPortID < _instance->m_numofHdmiInput ) + { + newPhyAddr = _instance->hdmiInputs[newPortID].m_physicalAddr; + } + else + { + LOGERR("Invalid HDMI New Port ID"); + return; + } + } + + if(!(_instance->smConnection)) + return; + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(RoutingChange(oldPhyAddr, newPhyAddr)), 500); + } + + void HdmiCecSinkImplementation::addDevice(const int logicalAddress) { + JsonObject params; + + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if ( !HdmiCecSinkImplementation::_instance->deviceList[logicalAddress].m_isDevicePresent ) + { + HdmiCecSinkImplementation::_instance->deviceList[logicalAddress].m_isDevicePresent = true; + HdmiCecSinkImplementation::_instance->deviceList[logicalAddress].m_logicalAddress = LogicalAddress(logicalAddress); + HdmiCecSinkImplementation::_instance->m_numberOfDevices++; + HdmiCecSinkImplementation::_instance->m_pollNextState = POLL_THREAD_STATE_INFO; + + if(logicalAddress == 0x5) + { + LOGINFO(" logicalAddress =%d , Audio device detected, Notify Device Settings", logicalAddress ); + hdmiCecAudioDeviceConnected = true; + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ReportAudioDeviceConnectedStatus("success", "true"); + index++; + } + } + + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnDeviceAdded(logicalAddress); + index++; + } + } + } + + void HdmiCecSinkImplementation::removeDevice(const int logicalAddress) { + JsonObject params; + + if(!HdmiCecSinkImplementation::_instance) + return; + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ + LOGERR("Logical Address NOT Allocated"); + return; + } + + if (_instance->deviceList[logicalAddress].m_isDevicePresent) + { + _instance->m_numberOfDevices--; + + for (int i=0; i < m_numofHdmiInput; i++) + { + if (_instance->deviceList[logicalAddress].m_physicalAddr.getByteValue(0) == (hdmiInputs[i].m_portID + 1)) { + hdmiInputs[i].removeChild(_instance->deviceList[logicalAddress].m_physicalAddr); + hdmiInputs[i].update(LogicalAddress(LogicalAddress::UNREGISTERED)); + } + } + + if(logicalAddress == 0x5) + { + LOGINFO(" logicalAddress =%d , Audio device removed, Notify Device Settings", logicalAddress ); + + hdmiCecAudioDeviceConnected = false; + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ReportAudioDeviceConnectedStatus("success", "false"); + index++; + } + } + + _instance->deviceList[logicalAddress].m_isRequestRetry = 0; + _instance->deviceList[logicalAddress].clear(); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->OnDeviceRemoved(logicalAddress); + index++; + } + } + } + + void HdmiCecSinkImplementation::request(const int logicalAddress) { + int requestType; + + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || logicalAddress >= LogicalAddress::UNREGISTERED + TEST_ADD ){ + LOGERR("Logical Address NOT Allocated Or its not valid"); + return; + } + + requestType = _instance->requestType(logicalAddress); + _instance->deviceList[logicalAddress].m_isRequested = requestType; + + switch (requestType) + { + case CECDeviceParams::REQUEST_PHISICAL_ADDRESS : + { + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GivePhysicalAddress()), 200); + } + break; + + case CECDeviceParams::REQUEST_CEC_VERSION : + { + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GetCECVersion()), 100); + } + break; + + case CECDeviceParams::REQUEST_DEVICE_VENDOR_ID : + { + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GiveDeviceVendorID()), 100); + } + break; + + case CECDeviceParams::REQUEST_OSD_NAME : + { + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GiveOSDName()), 500); + } + break; + + case CECDeviceParams::REQUEST_POWER_STATUS : + { + _instance->smConnection->sendTo(LogicalAddress(logicalAddress), MessageEncoder().encode(GiveDevicePowerStatus()), 100); + } + break; + default: + { + _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; + } + break; + } + + _instance->deviceList[logicalAddress].m_requestTime = std::chrono::system_clock::now(); + LOGINFO("request type %d", _instance->deviceList[logicalAddress].m_isRequested); + } + + int HdmiCecSinkImplementation::requestStatus(const int logicalAddress) { + std::chrono::duration elapsed; + bool isElapsed = false; + + if(!HdmiCecSinkImplementation::_instance) + return -1; + + + if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || logicalAddress >= LogicalAddress::UNREGISTERED + TEST_ADD ) { + LOGERR("Logical Address NOT Allocated Or its not valid"); + return -1; + } + + switch ( _instance->deviceList[logicalAddress].m_isRequested ) { + case CECDeviceParams::REQUEST_PHISICAL_ADDRESS : + { + if( _instance->deviceList[logicalAddress].m_isPAUpdated && + _instance->deviceList[logicalAddress].m_isDeviceTypeUpdated ) + { + _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; + } + } + break; + + case CECDeviceParams::REQUEST_CEC_VERSION : + { + if( _instance->deviceList[logicalAddress].m_isVersionUpdated ) + { + _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; + } + } + break; + + case CECDeviceParams::REQUEST_DEVICE_VENDOR_ID : + { + if( _instance->deviceList[logicalAddress].m_isVendorIDUpdated ) + { + _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; + } + } + break; + + case CECDeviceParams::REQUEST_OSD_NAME : + { + if( _instance->deviceList[logicalAddress].m_isOSDNameUpdated ) + { + _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; + } + } + break; + + case CECDeviceParams::REQUEST_POWER_STATUS : + { + if( _instance->deviceList[logicalAddress].m_isPowerStatusUpdated ) + { + _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; + } + } + break; + default: + break; + } + + if ( _instance->deviceList[logicalAddress].m_isRequested != CECDeviceParams::REQUEST_NONE ) + { + elapsed = std::chrono::system_clock::now() - _instance->deviceList[logicalAddress].m_requestTime; + + if ( elapsed.count() > HDMICECSINK_REQUEST_MAX_WAIT_TIME_MS ) + { + LOGINFO("request elapsed "); + isElapsed = true; + } + } + + if (isElapsed) + { + /* For some request it should be retry, like report physical address etc for other we can have default values */ + switch( _instance->deviceList[logicalAddress].m_isRequested ) + { + case CECDeviceParams::REQUEST_PHISICAL_ADDRESS : + { + LOGINFO("Retry for REQUEST_PHISICAL_ADDRESS = %d", _instance->deviceList[logicalAddress].m_isRequestRetry); + /* Update with Invalid Physical Address */ + if ( _instance->deviceList[logicalAddress].m_isRequestRetry++ >= HDMICECSINK_REQUEST_MAX_RETRY ) + { + LOGINFO("Max retry for REQUEST_PHISICAL_ADDRESS = %d", _instance->deviceList[logicalAddress].m_isRequestRetry); + _instance->deviceList[logicalAddress].update(PhysicalAddress(0xF,0xF,0xF,0xF)); + _instance->deviceList[logicalAddress].update(DeviceType(DeviceType::RESERVED)); + _instance->deviceList[logicalAddress].m_isRequestRetry = 0; + } + } + break; + + case CECDeviceParams::REQUEST_CEC_VERSION : + { + /*Defaulting to 1.4*/ + _instance->deviceList[logicalAddress].update(Version(Version::V_1_4)); + } + break; + + case CECDeviceParams::REQUEST_DEVICE_VENDOR_ID : + { + _instance->deviceList[logicalAddress].update(VendorID(0,0,0)); + } + break; + + case CECDeviceParams::REQUEST_OSD_NAME : + { + if ( _instance->deviceList[logicalAddress].m_isRequestRetry++ >= HDMICECSINK_REQUEST_MAX_RETRY ) + { + LOGINFO("Max retry for REQUEST_OSD_NAME = %d", _instance->deviceList[logicalAddress].m_isRequestRetry); + _instance->deviceList[logicalAddress].update(OSDName("")); + _instance->deviceList[logicalAddress].m_isRequestRetry = 0; + } + } + break; + + case CECDeviceParams::REQUEST_POWER_STATUS : + { + _instance->deviceList[logicalAddress].update(PowerStatus(PowerStatus::POWER_STATUS_NOT_KNOWN)); + } + break; + default: + break; + } + + + _instance->deviceList[logicalAddress].m_isRequested = CECDeviceParams::REQUEST_NONE; + } + + if( _instance->deviceList[logicalAddress].m_isRequested == CECDeviceParams::REQUEST_NONE) + { + LOGINFO("Request Done"); + return CECDeviceParams::REQUEST_DONE; + } + + //LOGINFO("Request NOT Done"); + return CECDeviceParams::REQUEST_NOT_DONE; + } + + void HdmiCecSinkImplementation::threadRun() + { + std::vector connected; + std::vector disconnected; + int logicalAddressRequested = LogicalAddress::UNREGISTERED + TEST_ADD; + bool isExit = false; + + if(!HdmiCecSinkImplementation::_instance) + return; + + if(!(_instance->smConnection)) + return; + LOGINFO("Entering ThreadRun: _instance->m_pollThreadExit %d isExit %d _instance->m_pollThreadState %d _instance->m_pollNextState %d",_instance->m_pollThreadExit,isExit,_instance->m_pollThreadState,_instance->m_pollNextState ); + _instance->m_sleepTime = HDMICECSINK_PING_INTERVAL_MS; + + while(1) + { + + if (_instance->m_pollThreadExit || isExit ){ + LOGWARN("Thread Exits _instance->m_pollThreadExit %d isExit %d _instance->m_pollThreadState %d _instance->m_pollNextState %d",_instance->m_pollThreadExit,isExit,_instance->m_pollThreadState,_instance->m_pollNextState ); + break; + } + + if ( _instance->m_pollNextState != POLL_THREAD_STATE_NONE ) + { + _instance->m_pollThreadState = _instance->m_pollNextState; + _instance->m_pollNextState = POLL_THREAD_STATE_NONE; + } + + switch (_instance->m_pollThreadState) { + + case POLL_THREAD_STATE_POLL : + { + //LOGINFO("POLL_THREAD_STATE_POLL"); + _instance->allocateLogicalAddress(DeviceType::TV); + if ( _instance->m_logicalAddressAllocated != LogicalAddress::UNREGISTERED) + { + logicalAddress = LogicalAddress(_instance->m_logicalAddressAllocated); + LibCCEC::getInstance().addLogicalAddress(logicalAddress); + _instance->smConnection->setSource(logicalAddress); + _instance->m_numberOfDevices = 0; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType = DeviceType::TV; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_isDevicePresent = true; + _instance->deviceList[_instance->m_logicalAddressAllocated].update(physical_addr); + _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_1_4; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_vendorID = appVendorId; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus = PowerStatus(powerState); + _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage = defaultLanguage; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_osdName = osdName.toString().c_str(); + if(cecVersion == 2.0) { + _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_2_0; + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), + MessageEncoder().encode(ReportFeatures(Version::V_2_0,allDevicetype,rcProfile,deviceFeatures)), 500); + } + _instance->smConnection->addFrameListener(_instance->msgFrameListener); + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), + MessageEncoder().encode(ReportPhysicalAddress(physical_addr, _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType)), 100); + + _instance->m_sleepTime = 0; + _instance->m_pollThreadState = POLL_THREAD_STATE_PING; + } + else + { + LOGINFO("Not able allocate Logical Address for TV"); + _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; + } + } + break; + + case POLL_THREAD_STATE_PING : + { + //LOGINFO("POLL_THREAD_STATE_PING"); + _instance->m_pollThreadState = POLL_THREAD_STATE_INFO; + connected.clear(); + disconnected.clear(); + _instance->pingDevices(connected, disconnected); + + if ( disconnected.size() ){ + for( unsigned int i=0; i< disconnected.size(); i++ ) + { + LOGWARN("Disconnected Devices [%zu]", disconnected.size()); + _instance->removeDevice(disconnected[i]); + } + } + + if (connected.size()) { + LOGWARN("Connected Devices [%zu]", connected.size()); + for( unsigned int i=0; i< connected.size(); i++ ) + { + _instance->addDevice(connected[i]); + /* If new device is connected, then try to aquire the information */ + _instance->m_pollThreadState = POLL_THREAD_STATE_INFO; + _instance->m_sleepTime = 0; + } + } + else + { + for(int i=0;im_logicalAddressAllocated && + _instance->deviceList[i].m_isDevicePresent && + !_instance->deviceList[i].isAllUpdated() ) + { + _instance->m_pollNextState = POLL_THREAD_STATE_INFO; + _instance->m_sleepTime = 0; + } + } + /* Check for any update required */ + _instance->m_pollThreadState = POLL_THREAD_STATE_UPDATE; + _instance->m_sleepTime = 0; + } + } + break; + + case POLL_THREAD_STATE_INFO : + { + //LOGINFO("POLL_THREAD_STATE_INFO"); + + if ( logicalAddressRequested == LogicalAddress::UNREGISTERED + TEST_ADD ) + { + int i = 0; + for(;im_logicalAddressAllocated && + _instance->deviceList[i].m_isDevicePresent && + !_instance->deviceList[i].isAllUpdated() ) + { + //LOGINFO("POLL_THREAD_STATE_INFO -> request for %d", i); + logicalAddressRequested = i; + _instance->request(logicalAddressRequested); + _instance->m_sleepTime = HDMICECSINK_REQUEST_INTERVAL_TIME_MS; + break; + } + } + + if ( i == LogicalAddress::UNREGISTERED) + { + /*So there is no update required, try to ping after some seconds*/ + _instance->m_pollThreadState = POLL_THREAD_STATE_IDLE; + _instance->m_sleepTime = 0; + //LOGINFO("POLL_THREAD_STATE_INFO -> state change to Ping", i); + } + } + else + { + /*So there is request sent for logical address, so wait and check the status */ + if ( _instance->requestStatus(logicalAddressRequested) == CECDeviceParams::REQUEST_DONE ) + { + logicalAddressRequested = LogicalAddress::UNREGISTERED; + } + else + { + _instance->m_sleepTime = HDMICECSINK_REQUEST_INTERVAL_TIME_MS; + } + } + } + break; + + /* updating the power status and if required we can add other information later*/ + case POLL_THREAD_STATE_UPDATE : + { + //LOGINFO("POLL_THREAD_STATE_UPDATE"); + + for(int i=0;im_logicalAddressAllocated && + _instance->deviceList[i].m_isDevicePresent && + _instance->deviceList[i].m_isPowerStatusUpdated ) + { + std::chrono::duration elapsed = std::chrono::system_clock::now() - _instance->deviceList[i].m_lastPowerUpdateTime; + + if ( elapsed.count() > HDMICECSINK_UPDATE_POWER_STATUS_INTERVA_MS ) + { + _instance->deviceList[i].m_isPowerStatusUpdated = false; + _instance->m_pollNextState = POLL_THREAD_STATE_INFO; + _instance->m_sleepTime = 0; + } + } + } + + _instance->m_pollThreadState = POLL_THREAD_STATE_IDLE; + _instance->m_sleepTime = 0; + } + break; + + case POLL_THREAD_STATE_IDLE : + { + //LOGINFO("POLL_THREAD_STATE_IDLE"); + _instance->m_sleepTime = HDMICECSINK_PING_INTERVAL_MS; + _instance->m_pollThreadState = POLL_THREAD_STATE_PING; + } + break; + + case POLL_THREAD_STATE_WAIT : + { + /* Wait for Hdmi is connected, in case it disconnected */ + //LOGINFO("19Aug2020-[01] -> POLL_THREAD_STATE_WAIT"); + _instance->m_sleepTime = HDMICECSINK_WAIT_FOR_HDMI_IN_MS; + + if ( _instance->m_isHdmiInConnected == true ) + { + _instance->m_pollThreadState = POLL_THREAD_STATE_POLL; + } + } + break; + + case POLL_THREAD_STATE_EXIT : + { + isExit = true; + _instance->m_sleepTime = 0; + } + break; + } + + std::unique_lock lk(_instance->m_pollExitMutex); + if ( _instance->m_ThreadExitCV.wait_for(lk, std::chrono::milliseconds(_instance->m_sleepTime)) == std::cv_status::timeout ) + continue; + else + LOGINFO("Thread is going to Exit m_pollThreadExit %d\n", _instance->m_pollThreadExit ); + + } + } + + void HdmiCecSinkImplementation::allocateLAforTV() + { + bool gotLogicalAddress = false; + int addr = LogicalAddress::TV; + int i, j; + if (!(_instance->smConnection)) + return; + + for (i = 0; i< HDMICECSINK_NUMBER_TV_ADDR; i++) + { + /* poll for TV logical address - retry 5 times*/ + for (j = 0; j < 5; j++) + { + try { + smConnection->poll(LogicalAddress(addr), Throw_e()); + } + catch(CECNoAckException &e ) + { + LOGWARN("Poll caught %s \r\n",e.what()); + gotLogicalAddress = true; + break; + } + catch(Exception &e) + { + LOGWARN("Poll caught %s \r\n",e.what()); + usleep(250000); + } + } + if (gotLogicalAddress) + { + break; + } + addr = LogicalAddress::SPECIFIC_USE; + } + + if ( gotLogicalAddress ) + { + m_logicalAddressAllocated = addr; + } + else + { + m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; + } + + LOGWARN("Logical Address for TV 0x%x \r\n",m_logicalAddressAllocated); + } + + void HdmiCecSinkImplementation::allocateLogicalAddress(int deviceType) + { + if( deviceType == DeviceType::TV ) + { + allocateLAforTV(); + } + } + + void HdmiCecSinkImplementation::CECEnable(void) + { + std::lock_guard lock(m_enableMutex); + JsonObject params; + LOGINFO("Entered CECEnable"); + if (cecEnableStatus) + { + LOGWARN("CEC Already Enabled"); + return; + } + + if(0 == libcecInitStatus) + { + try + { + LibCCEC::getInstance().init("HdmiCecSink"); + } + catch (const std::exception& e) + { + LOGWARN("CEC exception caught from LibCCEC::getInstance().init()"); + } + } + libcecInitStatus++; + + //Acquire CEC Addresses + getPhysicalAddress(); + + smConnection = new Connection(LogicalAddress::UNREGISTERED,false,"ServiceManager::Connection::"); + smConnection->open(); + allocateLogicalAddress(DeviceType::TV); + LOGINFO("logical address allocalted: %x \n",m_logicalAddressAllocated); + if ( m_logicalAddressAllocated != LogicalAddress::UNREGISTERED && smConnection) + { + logicalAddress = LogicalAddress(m_logicalAddressAllocated); + LOGINFO(" add logical address %x \n",m_logicalAddressAllocated); + LibCCEC::getInstance().addLogicalAddress(logicalAddress); + smConnection->setSource(logicalAddress); + } + msgProcessor = new HdmiCecSinkProcessor(*smConnection); + msgFrameListener = new HdmiCecSinkFrameListener(*msgProcessor); + if(smConnection) + { + LOGWARN("Start Thread %p", smConnection ); + m_pollThreadState = POLL_THREAD_STATE_POLL; + m_pollNextState = POLL_THREAD_STATE_NONE; + m_pollThreadExit = false; + m_pollThread = std::thread(threadRun); + } + cecEnableStatus = true; + + params["cecEnable"] = string("true"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ReportCecEnabledEvent("true"); + index++; + } + + return; + } + + void HdmiCecSinkImplementation::CECDisable(void) + { + std::lock_guard lock(m_enableMutex); + JsonObject params; + LOGINFO("Entered CECDisable "); + if(!cecEnableStatus) + { + LOGWARN("CEC Already Disabled "); + return; + } + + if(m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED) + { + stopArc(); + while(m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED) + { + usleep(500000); + } + } + + LOGINFO(" CECDisable ARC stopped "); + cecEnableStatus = false; + if (smConnection != NULL) + { + LOGWARN("Stop Thread %p", smConnection ); + m_pollThreadExit = true; + m_ThreadExitCV.notify_one(); + + try + { + if (m_pollThread.joinable()) + { + LOGWARN("Join Thread %p", smConnection ); + m_pollThread.join(); + } + } + catch(const std::system_error& e) + { + LOGERR("system_error exception in thread join %s", e.what()); + } + catch(const std::exception& e) + { + LOGERR("exception in thread join %s", e.what()); + } + + m_pollThreadState = POLL_THREAD_STATE_NONE; + m_pollNextState = POLL_THREAD_STATE_NONE; + + LOGWARN("Deleted Thread %p", smConnection ); + + smConnection->close(); + delete smConnection; + smConnection = NULL; + } + + m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; + m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + + for(int i=0; i< 16; i++) + { + if (_instance->deviceList[i].m_isDevicePresent) + { + _instance->deviceList[i].clear(); + } + } + + if(1 == libcecInitStatus) + { + try + { + LibCCEC::getInstance().term(); + } + catch (const std::exception& e) + { + LOGWARN("CEC exception caught from LibCCEC::getInstance().term() "); + } + } + + libcecInitStatus--; + LOGWARN("CEC Disabled %d",libcecInitStatus); + + params["cecEnable"] = string("false"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ReportCecEnabledEvent("false"); + index++; + } + + return; + } + + + void HdmiCecSinkImplementation::getPhysicalAddress() + { + LOGINFO("Entered getPhysicalAddress "); + + uint32_t physAddress = 0x0F0F0F0F; + + try { + LibCCEC::getInstance().getPhysicalAddress(&physAddress); + physical_addr = {(uint8_t)((physAddress >> 24) & 0xFF),(uint8_t)((physAddress >> 16) & 0xFF),(uint8_t) ((physAddress >> 8) & 0xFF),(uint8_t)((physAddress) & 0xFF)}; + LOGINFO("getPhysicalAddress: physicalAddress: %s ", physical_addr.toString().c_str()); + } + catch (const std::exception& e) + { + LOGWARN("exception caught from getPhysicalAddress"); + } + return; + } + + bool HdmiCecSinkImplementation::getEnabled() + { + + + LOGINFO("getEnabled :%d ",cecEnableStatus); + if(true == cecEnableStatus) + return true; + else + return false; + } + + bool HdmiCecSinkImplementation::getAudioDeviceConnectedStatus() + { + LOGINFO("getAudioDeviceConnectedStatus :%d ", hdmiCecAudioDeviceConnected); + if(true == hdmiCecAudioDeviceConnected) + return true; + else + return false; + } + //Arc Routing related functions + void HdmiCecSinkImplementation::startArc() + { + if ( cecEnableStatus != true ) + { + LOGINFO("Initiate_Arc Cec is disabled-> EnableCEC first"); + return; + } + if(!HdmiCecSinkImplementation::_instance) + return; + + LOGINFO("Current ARC State : %d\n", m_currentArcRoutingState); + + _instance->requestArcInitiation(); + + // start initiate ARC timer 3 sec + if (m_arcStartStopTimer.isActive()) + { + m_arcStartStopTimer.stop(); + } + m_arcstarting = true; + m_arcStartStopTimer.start((HDMISINK_ARC_START_STOP_MAX_WAIT_MS)); + + } + void HdmiCecSinkImplementation::requestArcInitiation() + { + { + std::lock_guard lock(m_arcRoutingStateMutex); + m_currentArcRoutingState = ARC_STATE_REQUEST_ARC_INITIATION; + } + LOGINFO("requestArcInitiation release sem"); + _instance->m_semSignaltoArcRoutingThread.release(); + + } + void HdmiCecSinkImplementation::stopArc() + { + if ( cecEnableStatus != true ) + { + LOGINFO("Initiate_Arc Cec is disabled-> EnableCEC first"); + return; + } + if(!HdmiCecSinkImplementation::_instance) + return; + if(m_currentArcRoutingState == ARC_STATE_REQUEST_ARC_TERMINATION || m_currentArcRoutingState == ARC_STATE_ARC_TERMINATED) + { + LOGINFO("ARC is either Termination in progress or already Terminated"); + return; + } + + _instance->requestArcTermination(); + /* start a timer for 3 sec to get the desired ARC_STATE_ARC_TERMINATED */ + if (m_arcStartStopTimer.isActive()) + { + m_arcStartStopTimer.stop(); + } + /* m_arcstarting = true means starting the ARC start timer ,false means ARC stopping timer*/ + m_arcstarting = false; + m_arcStartStopTimer.start((HDMISINK_ARC_START_STOP_MAX_WAIT_MS)); + + + } + void HdmiCecSinkImplementation::requestArcTermination() + { + { + std::lock_guard lock(m_arcRoutingStateMutex); + m_currentArcRoutingState = ARC_STATE_REQUEST_ARC_TERMINATION; + } + LOGINFO("requestArcTermination release sem"); + _instance->m_semSignaltoArcRoutingThread.release(); + + } + + void HdmiCecSinkImplementation::Process_InitiateArc() + { + JsonObject params; + + LOGINFO("Command: INITIATE_ARC \n"); + + if(!HdmiCecSinkImplementation::_instance) + return; + + //DD: Check cecSettingEnabled to prevent race conditions which gives immediate UI setting status + //Initiate ARC message may come from AVR/Soundbar while CEC disable is in-progress + if ( cecSettingEnabled != true ) + { + LOGINFO("Process InitiateArc from Audio device: Cec is disabled-> EnableCEC first"); + return; + } + + LOGINFO("Got : INITIATE_ARC and current Arcstate is %d\n",_instance->m_currentArcRoutingState); + + if (m_arcStartStopTimer.isActive()) + { + m_arcStartStopTimer.stop(); + } + if (powerState == DEVICE_POWER_STATE_ON ) { + LOGINFO("Notifying Arc Initiation event as power state is %s", powerState ? "Off" : "On"); + std::lock_guard lock(_instance->m_arcRoutingStateMutex); + _instance->m_currentArcRoutingState = ARC_STATE_ARC_INITIATED; + + _instance->m_semSignaltoArcRoutingThread.release(); + LOGINFO("Got : ARC_INITIATED and notify Device setting"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ArcInitiationEvent("success"); + index++; + } + } else { + LOGINFO("Not notifying Arc Initiation event as power state is %s", powerState ? "Off" : "On"); + } + + } + void HdmiCecSinkImplementation::Process_TerminateArc() + { + JsonObject params; + + LOGINFO("Command: TERMINATE_ARC current arc state %d \n",HdmiCecSinkImplementation::_instance->m_currentArcRoutingState); + if (m_arcStartStopTimer.isActive()) + { + m_arcStartStopTimer.stop(); + } + std::lock_guard lock(m_arcRoutingStateMutex); + HdmiCecSinkImplementation::_instance->m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + _instance->m_semSignaltoArcRoutingThread.release(); + + // trigger callback to Device setting informing to TERMINATE_ARC + LOGINFO("Got : ARC_TERMINATED and notify Device setting"); + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ArcTerminationEvent("success"); + index++; + } + } + + void HdmiCecSinkImplementation::threadSendKeyEvent() + { + if(!HdmiCecSinkImplementation::_instance) + return; + + SendKeyInfo keyInfo = {-1,-1}; + + while(!_instance->m_sendKeyEventThreadExit) + { + keyInfo.logicalAddr = -1; + keyInfo.keyCode = -1; + { + // Wait for a message to be added to the queue + std::unique_lock lk(_instance->m_sendKeyEventMutex); + _instance->m_sendKeyCV.wait(lk, []{return (_instance->m_sendKeyEventThreadRun == true);}); + } + + if (_instance->m_sendKeyEventThreadExit == true) + { + LOGINFO(" threadSendKeyEvent Exiting"); + _instance->m_sendKeyEventThreadRun = false; + break; + } + + if (_instance->m_SendKeyQueue.empty()) { + _instance->m_sendKeyEventThreadRun = false; + continue; + } + + keyInfo = _instance->m_SendKeyQueue.front(); + _instance->m_SendKeyQueue.pop(); + + if(keyInfo.UserControl == "sendUserControlPressed" ) + { + LOGINFO("sendUserControlPressed : logical addr:0x%x keyCode: 0x%x queue size :%zu \n",keyInfo.logicalAddr,keyInfo.keyCode,_instance->m_SendKeyQueue.size()); + _instance->sendUserControlPressed(keyInfo.logicalAddr,keyInfo.keyCode); + } + else if(keyInfo.UserControl == "sendUserControlReleased") + { + LOGINFO("sendUserControlReleased : logical addr:0x%x queue size :%zu \n",keyInfo.logicalAddr,_instance->m_SendKeyQueue.size()); + _instance->sendUserControlReleased(keyInfo.logicalAddr); + } + else + { + LOGINFO("sendKeyPressEvent : logical addr:0x%x keyCode: 0x%x queue size :%zu \n",keyInfo.logicalAddr,keyInfo.keyCode,_instance->m_SendKeyQueue.size()); + _instance->sendKeyPressEvent(keyInfo.logicalAddr,keyInfo.keyCode); + _instance->sendKeyReleaseEvent(keyInfo.logicalAddr); + } + + if((_instance->m_SendKeyQueue.size()<=1 || (_instance->m_SendKeyQueue.size() % 2 == 0)) && ((keyInfo.keyCode == VOLUME_UP) || (keyInfo.keyCode == VOLUME_DOWN) || (keyInfo.keyCode == MUTE)) ) + { + _instance->sendGiveAudioStatusMsg(); + } + + }//while(!_instance->m_sendKeyEventThreadExit) + }//threadSendKeyEvent + + + void HdmiCecSinkImplementation::threadArcRouting() + { + bool isExit = false; + uint32_t currentArcRoutingState; + + if(!HdmiCecSinkImplementation::_instance) + return; + + LOGINFO("Running threadArcRouting"); + + + while(1) + { + + _instance->m_semSignaltoArcRoutingThread.acquire(); + + + + { + LOGINFO(" threadArcRouting Got semaphore"); + std::lock_guard lock(_instance->m_arcRoutingStateMutex); + + currentArcRoutingState = _instance->m_currentArcRoutingState; + + LOGINFO(" threadArcRouting Got Sem arc state %d",currentArcRoutingState); + } + + switch (currentArcRoutingState) + { + + case ARC_STATE_REQUEST_ARC_INITIATION : + { + + _instance->systemAudioModeRequest(); + _instance->Send_Request_Arc_Initiation_Message(); + + } + break; + case ARC_STATE_ARC_INITIATED : + { + _instance->Send_Report_Arc_Initiated_Message(); + } + break; + case ARC_STATE_REQUEST_ARC_TERMINATION : + { + + _instance->Send_Request_Arc_Termination_Message(); + + } + break; + case ARC_STATE_ARC_TERMINATED : + { + _instance->Send_Report_Arc_Terminated_Message(); + } + break; + case ARC_STATE_ARC_EXIT : + { + isExit = true; + } + break; + } + + if (isExit == true) + { + LOGINFO(" threadArcRouting EXITing"); + break; + } + }//while(1) + }//threadArcRouting + + void HdmiCecSinkImplementation::Send_Request_Arc_Initiation_Message() + { + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + LOGINFO(" Send_Request_Arc_Initiation_Message "); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestArcInitiation()), 1000); + + } + void HdmiCecSinkImplementation::Send_Report_Arc_Initiated_Message() + { + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(ReportArcInitiation()), 1000); + + } + void HdmiCecSinkImplementation::Send_Request_Arc_Termination_Message() + { + + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestArcTermination()), 1000); + } + + void HdmiCecSinkImplementation::Send_Report_Arc_Terminated_Message() + { + if(!HdmiCecSinkImplementation::_instance) + return; + if(!(_instance->smConnection)) + return; + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(ReportArcTermination()), 1000); + + } + + void HdmiCecSinkImplementation::getHdmiArcPortID() + { + int err; + dsGetHDMIARCPortIdParam_t param; + err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, + (char *)IARM_BUS_DSMGR_API_dsGetHDMIARCPortId, + (void *)¶m, + sizeof(param)); + if (IARM_RESULT_SUCCESS == err) + { + LOGINFO("HDMI ARC port ID HdmiArcPortID=[%d] \n", param.portId); + HdmiArcPortID = param.portId; + } + } + + void HdmiCecSinkImplementation::getCecVersion() + { + RFC_ParamData_t param = {0}; + WDMP_STATUS status = getRFCParameter((char*)"thunderapi", TR181_HDMICECSINK_CEC_VERSION, ¶m); + if(WDMP_SUCCESS == status && param.type == WDMP_STRING) { + LOGINFO("CEC Version from RFC = [%s] \n", param.value); + cecVersion = atof(param.value); + } + else { + LOGINFO("Error while fetching CEC Version from RFC "); + } + } + + } // namespace Plugin +} // namespace WPEFrameworklk diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h new file mode 100644 index 00000000..4a787a54 --- /dev/null +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -0,0 +1,748 @@ +/** +* If not stated otherwise in this file or this component's LICENSE +* file the following copyright and licenses apply: +* +* Copyright 2019 RDK Management +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +**/ + +#pragma once + +#include +#include "ccec/FrameListener.hpp" +#include "ccec/Connection.hpp" + +#include "libIARM.h" +#include "ccec/Assert.hpp" +#include "ccec/Messages.hpp" +#include "ccec/MessageDecoder.hpp" +#include "ccec/MessageProcessor.hpp" + +#undef Assert // this define from Connection.hpp conflicts with WPEFramework + +#include "Module.h" +#include "tptimer.h" +#include +#include +#include +#include + +#include "UtilsLogging.h" +#include +#include "PowerManagerInterface.h" + +using namespace WPEFramework; +using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; +using ThermalTemperature = WPEFramework::Exchange::IPowerManager::ThermalTemperature; + + +namespace WPEFramework { + + namespace Plugin { + class HdmiCecSinkFrameListener : public FrameListener + { + public: + HdmiCecSinkFrameListener(MessageProcessor &processor) : processor(processor) {} + void notify(const CECFrame &in) const; + ~HdmiCecSinkFrameListener() {} + private: + MessageProcessor &processor; + }; + + class HdmiCecSinkProcessor : public MessageProcessor + { + public: + HdmiCecSinkProcessor(Connection &conn) : conn(conn) {} + void process (const ActiveSource &msg, const Header &header); + void process (const InActiveSource &msg, const Header &header); + void process (const ImageViewOn &msg, const Header &header); + void process (const TextViewOn &msg, const Header &header); + void process (const RequestActiveSource &msg, const Header &header); + void process (const Standby &msg, const Header &header); + void process (const GetCECVersion &msg, const Header &header); + void process (const CECVersion &msg, const Header &header); + void process (const SetMenuLanguage &msg, const Header &header); + void process (const GiveOSDName &msg, const Header &header); + void process (const GivePhysicalAddress &msg, const Header &header); + void process (const GiveDeviceVendorID &msg, const Header &header); + void process (const SetOSDString &msg, const Header &header); + void process (const SetOSDName &msg, const Header &header); + void process (const RoutingChange &msg, const Header &header); + void process (const RoutingInformation &msg, const Header &header); + void process (const SetStreamPath &msg, const Header &header); + void process (const GetMenuLanguage &msg, const Header &header); + void process (const ReportPhysicalAddress &msg, const Header &header); + void process (const DeviceVendorID &msg, const Header &header); + void process (const GiveDevicePowerStatus &msg, const Header &header); + void process (const ReportPowerStatus &msg, const Header &header); + void process (const FeatureAbort &msg, const Header &header); + void process (const Abort &msg, const Header &header); + void process (const Polling &msg, const Header &header); + void process (const InitiateArc &msg, const Header &header); + void process (const TerminateArc &msg, const Header &header); + void process (const ReportShortAudioDescriptor &msg, const Header &header); + void process (const SetSystemAudioMode &msg, const Header &header); + void process (const ReportAudioStatus &msg, const Header &header); + void process (const GiveFeatures &msg, const Header &header); + void process (const RequestCurrentLatency &msg, const Header &header); + private: + Connection conn; + void printHeader(const Header &header) + { + printf("Header : From : %s \n", header.from.toString().c_str()); + printf("Header : to : %s \n", header.to.toString().c_str()); + } + + }; + + class CECDeviceParams { + public: + + enum { + REQUEST_NONE = 0, + REQUEST_PHISICAL_ADDRESS = 1, + REQUEST_CEC_VERSION, + REQUEST_DEVICE_VENDOR_ID, + REQUEST_POWER_STATUS, + REQUEST_OSD_NAME, + }; + + enum { + REQUEST_DONE = 0, + REQUEST_NOT_DONE, + REQUEST_TIME_ELAPSED, + }; + + DeviceType m_deviceType; + LogicalAddress m_logicalAddress; + PhysicalAddress m_physicalAddr; + Version m_cecVersion; + VendorID m_vendorID; + OSDName m_osdName; + PowerStatus m_powerStatus; + bool m_isDevicePresent; + bool m_isDeviceDisconnected; + Language m_currentLanguage; + bool m_isActiveSource; + bool m_isDeviceTypeUpdated; + bool m_isPAUpdated; + bool m_isVersionUpdated; + bool m_isOSDNameUpdated; + bool m_isVendorIDUpdated; + bool m_isPowerStatusUpdated; + int m_isRequested; + int m_isRequestRetry; + std::chrono::system_clock::time_point m_requestTime; + std::vector m_featureAborts; + std::chrono::system_clock::time_point m_lastPowerUpdateTime; + + CECDeviceParams() + : m_deviceType(0), m_logicalAddress(0),m_physicalAddr(0x0f,0x0f,0x0f,0x0f),m_cecVersion(0),m_vendorID(0,0,0),m_osdName(""),m_powerStatus(0),m_currentLanguage("") + { + m_isDevicePresent = false; + m_isActiveSource = false; + m_isPAUpdated = false; + m_isVersionUpdated = false; + m_isOSDNameUpdated = false; + m_isVendorIDUpdated = false; + m_isPowerStatusUpdated = false; + m_isDeviceDisconnected = false; + m_isDeviceTypeUpdated = false; + m_isRequestRetry = 0; + } + + void clear( ) + { + m_deviceType = 0; + m_logicalAddress = 0; + m_physicalAddr = PhysicalAddress(0x0f,0x0f,0x0f,0x0f); + m_cecVersion = 0; + m_vendorID = VendorID(0,0,0); + m_osdName = ""; + m_powerStatus = 0; + m_currentLanguage = ""; + m_isDevicePresent = false; + m_isActiveSource = false; + m_isPAUpdated = false; + m_isVersionUpdated = false; + m_isOSDNameUpdated = false; + m_isVendorIDUpdated = false; + m_isPowerStatusUpdated = false; + m_isDeviceDisconnected = false; + m_isDeviceTypeUpdated = false; + } + + void printVariable() + { + LOGWARN("Device LogicalAddress %s", m_logicalAddress.toString().c_str()); + LOGWARN("Device Type %s", m_deviceType.toString().c_str()); + LOGWARN("Device Present %d", m_isDevicePresent); + LOGWARN("Active Source %d", m_isActiveSource); + LOGWARN("PA Updated %d", m_isPAUpdated); + LOGWARN("Version Updated %d", m_isVersionUpdated); + LOGWARN("OSDName Updated %d", m_isOSDNameUpdated); + LOGWARN("PowerStatus Updated %d", m_isPowerStatusUpdated); + LOGWARN("VendorID Updated %d", m_isPowerStatusUpdated); + LOGWARN("CEC Version : %s", m_cecVersion.toString().c_str()); + LOGWARN("Vendor ID : %s", m_vendorID.toString().c_str()); + LOGWARN("PhisicalAddress : %s", m_physicalAddr.toString().c_str()); + LOGWARN("OSDName : %s", m_osdName.toString().c_str()); + LOGWARN("Power Status : %s", m_powerStatus.toString().c_str()); + LOGWARN("Language : %s", m_currentLanguage.toString().c_str()); + } + + bool isAllUpdated() { + if( !m_isPAUpdated + || !m_isVersionUpdated + || !m_isOSDNameUpdated + || !m_isVendorIDUpdated + || !m_isPowerStatusUpdated + || !m_isDeviceTypeUpdated ){ + return false; + } + return true; + } + + void update( const DeviceType &deviceType ) { + m_deviceType = deviceType; + m_isDeviceTypeUpdated = true; + } + + void update( const PhysicalAddress &physical_addr ) { + m_physicalAddr = physical_addr; + m_isPAUpdated = true; + } + + void update ( const VendorID &vendorId) { + m_vendorID = vendorId; + m_isVendorIDUpdated = true; + } + + void update ( const Version &version ) { + m_cecVersion = version; + m_isVersionUpdated = true; + } + + void update ( const OSDName &osdName ) { + m_osdName = osdName; + m_isOSDNameUpdated = true; + } + + void update ( const PowerStatus &status ) { + m_powerStatus = status; + m_isPowerStatusUpdated = true; + m_lastPowerUpdateTime = std::chrono::system_clock::now(); + } + }; + + class DeviceNode { + public: + uint8_t m_childsLogicalAddr[LogicalAddress::UNREGISTERED]; + + DeviceNode() { + int i; + for (i = 0; i < LogicalAddress::UNREGISTERED; i++ ) + { + m_childsLogicalAddr[i] = LogicalAddress::UNREGISTERED; + } + } + + } ; + typedef struct sendKeyInfo + { + int logicalAddr; + int keyCode; + string UserControl; + }SendKeyInfo; + + class HdmiPortMap { + public: + uint8_t m_portID; + bool m_isConnected; + LogicalAddress m_logicalAddr; + PhysicalAddress m_physicalAddr; + DeviceNode m_deviceChain[3]; + + HdmiPortMap(uint8_t portID) : m_portID(portID), + m_logicalAddr(LogicalAddress::UNREGISTERED), + m_physicalAddr(portID+1,0,0,0) + { + m_isConnected = false; + } + + void update(bool isConnected) + { + m_isConnected = isConnected; + } + + void update( const LogicalAddress &addr ) + { + m_logicalAddr = addr; + } + + void addChild( const LogicalAddress &logical_addr, const PhysicalAddress &physical_addr ) + { + LOGINFO(" logicalAddr = %d, phisicalAddr = %s", m_logicalAddr.toInt(), physical_addr.toString().c_str()); + + if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED && + m_logicalAddr.toInt() != logical_addr.toInt() ) + { + LOGINFO(" update own logicalAddr = %d, new devcie logicalAddress = %d", m_logicalAddr.toInt(), logical_addr.toInt() ); + /* check matching with this port's physical address */ + if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && + physical_addr.getByteValue(1) != 0 ) + { + if ( physical_addr.getByteValue(3) != 0 ) + { + m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1] = logical_addr.toInt(); + } + else if ( physical_addr.getByteValue(2) != 0 ) + { + m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1] = logical_addr.toInt(); + } + else if ( physical_addr.getByteValue(1) != 0 ) + { + m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1] = logical_addr.toInt(); + } + } + } + else if ( physical_addr == m_physicalAddr ) + { + update(logical_addr); + LOGINFO(" update own logicalAddr = %d", m_logicalAddr.toInt()); + } + } + + void removeChild( PhysicalAddress &physical_addr ) + { + if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED ) + { + /* check matching with this port's physical address */ + if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && + physical_addr.getByteValue(1) != 0 ) + { + if ( physical_addr.getByteValue(3) != 0 ) + { + m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1] = LogicalAddress::UNREGISTERED; + } + else if ( physical_addr.getByteValue(2) != 0 ) + { + m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1] = LogicalAddress::UNREGISTERED; + } + else if ( physical_addr.getByteValue(1) != 0 ) + { + m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1] = LogicalAddress::UNREGISTERED; + } + } + } + } + + void getRoute( PhysicalAddress &physical_addr, std::vector & route ) + { + LOGINFO(" logicalAddr = %d, phsical = %s", m_logicalAddr.toInt(), physical_addr.toString().c_str()); + + if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED ) + { + LOGINFO(" search for logicalAddr = %d", m_logicalAddr.toInt()); + /* check matching with this port's physical address */ + if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && + physical_addr.getByteValue(1) != 0 ) + { + if ( physical_addr.getByteValue(3) != 0 ) + { + route.push_back(m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1]); + } + + if ( physical_addr.getByteValue(2) != 0 ) + { + route.push_back(m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1]); + } + + if ( physical_addr.getByteValue(1) != 0 ) + { + route.push_back(m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1]); + } + + route.push_back(m_logicalAddr.toInt()); + } + else + { + route.push_back(m_logicalAddr.toInt()); + LOGINFO("logicalAddr = %d, physical = %s", m_logicalAddr.toInt(), m_physicalAddr.toString().c_str()); + } + } + } + }; + + class binary_semaphore { + + public: + + explicit binary_semaphore(int init_count = count_max) + + : count_(init_count) {} + + + + // P-operation / acquire + + void wait() + + { + + std::unique_lock lk(m_); + + cv_.wait(lk, [=]{ return 0 < count_; }); + + --count_; + + } + + bool try_wait() + + { + + std::lock_guard lk(m_); + + if (0 < count_) { + + --count_; + + return true; + + } else { + + return false; + + } + + } + + // V-operation / release + + void signal() + + { + + std::lock_guard lk(m_); + + if (count_ < count_max) { + + ++count_; + + cv_.notify_one(); + + } + + } + + + + // Lockable requirements + + void acquire() { wait(); } + + bool try_lock() { return try_wait(); } + + void release() { signal(); } + + + +private: + + static const int count_max = 1; + + int count_; + + std::mutex m_; + + std::condition_variable cv_; + +}; + // This is a server for a JSONRPC communication channel. + // For a plugin to be capable to handle JSONRPC, inherit from PluginHost::JSONRPC. + // By inheriting from this class, the plugin realizes the interface PluginHost::IDispatcher. + // This realization of this interface implements, by default, the following methods on this plugin + // - exists + // - register + // - unregister + // Any other methood to be handled by this plugin can be added can be added by using the + // templated methods Register on the PluginHost::JSONRPC class. + // As the registration/unregistration of notifications is realized by the class PluginHost::JSONRPC, + // this class exposes a public method called, Notify(), using this methods, all subscribed clients + // will receive a JSONRPC message as a notification, in case this method is called. + class HdmiCecSinkImplementation : public PluginHost::IPlugin, public PluginHost::JSONRPC { + + enum { + POLL_THREAD_STATE_NONE, + POLL_THREAD_STATE_IDLE, + POLL_THREAD_STATE_POLL, + POLL_THREAD_STATE_PING, + POLL_THREAD_STATE_INFO, + POLL_THREAD_STATE_WAIT, + POLL_THREAD_STATE_CLEAN, + POLL_THREAD_STATE_UPDATE, + POLL_THREAD_STATE_EXIT, + }; + enum { + ARC_STATE_REQUEST_ARC_INITIATION, + ARC_STATE_ARC_INITIATED, + ARC_STATE_REQUEST_ARC_TERMINATION, + ARC_STATE_ARC_TERMINATED, + ARC_STATE_ARC_EXIT + }; + enum { + VOLUME_UP = 0x41, + VOLUME_DOWN = 0x42, + MUTE = 0x43, + UP = 0x01, + DOWN = 0x02, + LEFT = 0x03, + RIGHT = 0x04, + SELECT = 0x00, + HOME = 0x09, + BACK = 0x0D, + NUMBER_0 = 0x20, + NUMBER_1 = 0x21, + NUMBER_2 = 0x22, + NUMBER_3 = 0x23, + NUMBER_4 = 0x24, + NUMBER_5 = 0x25, + NUMBER_6 = 0x26, + NUMBER_7 = 0x27, + NUMBER_8 = 0x28, + NUMBER_9 = 0x29 + }; + public: + HdmiCecSinkImplementation(); + virtual ~HdmiCecSinkImplementation(); + virtual const string Initialize(PluginHost::IShell* shell) override; + virtual void Deinitialize(PluginHost::IShell* service) override; + virtual string Information() const override { return {}; } + static HdmiCecSinkImplementation* _instance; + CECDeviceParams deviceList[16]; + std::vector hdmiInputs; + int m_currentActiveSource; + void updateInActiveSource(const int logical_address, const InActiveSource &source ); + void updateActiveSource(const int logical_address, const ActiveSource &source ); + void updateTextViewOn(const int logicalAddress); + void updateImageViewOn(const int logicalAddress); + void updateDeviceChain(const LogicalAddress &logicalAddress, const PhysicalAddress &phy_addr); + void getActiveRoute(const LogicalAddress &logicalAddress, std::vector &route); + void removeDevice(const int logicalAddress); + void addDevice(const int logicalAddress); + void printDeviceList(); + void setStreamPath( const PhysicalAddress &physical_addr); + void setRoutingChange(const std::string &from, const std::string &to); + void sendStandbyMessage(); + void setCurrentLanguage(const Language &lang); + void sendMenuLanguage(); + void setActiveSource(bool isResponse); + void requestActiveSource(); + void startArc(); + void stopArc(); + void Process_InitiateArc(); + void Process_TerminateArc(); + void updateArcState(); + void requestShortaudioDescriptor(); + void Send_ShortAudioDescriptor_Event(JsonArray audiodescriptor); + void Process_ShortAudioDescriptor_msg(const ReportShortAudioDescriptor &msg); + void Process_SetSystemAudioMode_msg(const SetSystemAudioMode &msg); + void sendDeviceUpdateInfo(const int logicalAddress); + void sendFeatureAbort(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason); + void reportFeatureAbortEvent(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason); + void systemAudioModeRequest(); + void SendStandbyMsgEvent(const int logicalAddress); + void requestAudioDevicePowerStatus(); + void reportAudioDevicePowerStatusInfo(const int logicalAddress, const int powerStatus); + void updateCurrentLatency(int videoLatency, bool lowLatencyMode, int audioOutputCompensated, int audioOutputDelay); + void setLatencyInfo(); + void Process_ReportAudioStatus_msg(const ReportAudioStatus msg); + void sendKeyPressEvent(const int logicalAddress, int keyCode); + void sendKeyReleaseEvent(const int logicalAddress); + void sendUserControlPressed(const int logicalAddress, int keyCode); + void sendUserControlReleased(const int logicalAddress); + void sendGiveAudioStatusMsg(); + void onPowerModeChanged(const PowerState ¤tState, const PowerState &newState); + void registerEventHandlers(); + int m_numberOfDevices; /* Number of connected devices othethan own device */ + bool m_audioDevicePowerStatusRequested; + + BEGIN_INTERFACE_MAP(HdmiCecSinkImplementation) + INTERFACE_ENTRY(PluginHost::IPlugin) + INTERFACE_ENTRY(PluginHost::IDispatcher) + END_INTERFACE_MAP + + private: + class PowerManagerNotification : public Exchange::IPowerManager::IModeChangedNotification { + private: + PowerManagerNotification(const PowerManagerNotification&) = delete; + PowerManagerNotification& operator=(const PowerManagerNotification&) = delete; + + public: + explicit PowerManagerNotification(HdmiCecSinkImplementation& parent) + : _parent(parent) + { + } + ~PowerManagerNotification() override = default; + + public: + void OnPowerModeChanged(const PowerState ¤tState, const PowerState &newState) override + { + _parent.onPowerModeChanged(currentState, newState); + } + + template + T* baseInterface() + { + static_assert(std::is_base_of(), "base type mismatch"); + return static_cast(this); + } + + BEGIN_INTERFACE_MAP(PowerManagerNotification) + INTERFACE_ENTRY(Exchange::IPowerManager::IModeChangedNotification) + END_INTERFACE_MAP + + private: + HdmiCecSinkImplementation& _parent; + }; + // We do not allow this plugin to be copied !! + HdmiCecSinkImplementation(const HdmiCecSinkImplementation&) = delete; + HdmiCecSinkImplementation& operator=(const HdmiCecSinkImplementation&) = delete; + + //Begin methods + void InitializePowerManager(PluginHost::IShell *service); + //End methods + std::string logicalAddressDeviceType; + bool cecSettingEnabled; + bool cecOTPSettingEnabled; + bool cecEnableStatus; + bool hdmiCecAudioDeviceConnected; + bool m_isHdmiInConnected; + int m_numofHdmiInput; + uint8_t m_deviceType; + int m_logicalAddressAllocated; + std::thread m_pollThread; + uint32_t m_pollThreadState; + uint32_t m_pollNextState; + bool m_pollThreadExit; + uint32_t m_sleepTime; + std::mutex m_pollExitMutex; + std::mutex m_enableMutex; + /* Send Key event related */ + bool m_sendKeyEventThreadExit; + bool m_sendKeyEventThreadRun; + std::thread m_sendKeyEventThread; + std::mutex m_sendKeyEventMutex; + std::queue m_SendKeyQueue; + std::condition_variable m_sendKeyCV; + std::condition_variable m_ThreadExitCV; + + /* DALS - Latency Values */ + uint8_t m_video_latency; + uint8_t m_latency_flags; + uint8_t m_audio_output_delay; + + /* ARC related */ + std::thread m_arcRoutingThread; + uint32_t m_currentArcRoutingState; + std::mutex m_arcRoutingStateMutex; + binary_semaphore m_semSignaltoArcRoutingThread; + bool m_arcstarting; + TpTimer m_arcStartStopTimer; + + Connection *smConnection; + std::vector m_connectedDevices; + HdmiCecSinkProcessor *msgProcessor; + HdmiCecSinkFrameListener *msgFrameListener; + PowerManagerInterfaceRef _powerManagerPlugin; + Core::Sink _pwrMgrNotification; + bool _registeredEventHandlers; + const void InitializeIARM(); + void DeinitializeIARM(); + void allocateLogicalAddress(int deviceType); + void allocateLAforTV(); + void pingDevices(std::vector &connected , std::vector &disconnected); + void CheckHdmiInState(); + void request(const int logicalAddress); + int requestType(const int logicalAddress); + int requestStatus(const int logicalAddress); + static void threadRun(); + void cecMonitoringThread(); + static void dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); + void onHdmiHotPlug(int portId, int connectStatus); + bool loadSettings(); + void persistSettings(bool enableStatus); + void persistOTPSettings(bool enableStatus); + void persistOSDName(const char *name); + void persistVendorId(unsigned int vendorID); + void setEnabled(bool enabled); + bool getEnabled(); + bool getAudioDeviceConnectedStatus(); + void CECEnable(void); + void CECDisable(void); + void getPhysicalAddress(); + void getLogicalAddress(); + void cecAddressesChanged(int changeStatus); + + // Arc functions + + static void threadSendKeyEvent(); + static void threadArcRouting(); + void requestArcInitiation(); + void requestArcTermination(); + void Send_Request_Arc_Initiation_Message(); + void Send_Report_Arc_Initiated_Message(); + void Send_Request_Arc_Termination_Message(); + void Send_Report_Arc_Terminated_Message(); + void arcStartStopTimerFunction(); + void getHdmiArcPortID(); + void getCecVersion(); + + + public: + uint32_t GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute bool &success) override; + uint32_t GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) override; + uint32_t GetAudioDeviceConnectedStatus(bool &connected, bool &success) override; + uint32_t GetDeviceList(uint32_t &numberofdevices, IHdmiCecSinkDeviceListIterator*& deviceList, bool &success) override; + uint32_t GetEnabled(bool &enabled, bool &success) override; + uint32_t GetOSDName(string &name, bool &success) override; + uint32_t GetVendorId(string &vendorid, bool &success) override; + uint32_t PrintDeviceList(bool &printed, bool &success) override; + uint32_t RequestActiveSource(HdmiCecSinkSuccess &success) override; + uint32_t RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) override; + uint32_t SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) override; + uint32_t SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) override; + uint32_t SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; + uint32_t SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; + uint32_t SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) override; + uint32_t SendStandbyMessage(HdmiCecSinkSuccess &success) override; + uint32_t SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) override; + uint32_t SetActiveSource(HdmiCecSinkSuccess &success) override; + uint32_t SetEnabled(const bool enabled, HdmiCecSinkSuccess &success) override; + uint32_t SetOSDName(const string &name, HdmiCecSinkSuccess &success) override; + uint32_t SetRoutingChange(const string &oldPort, const string &newPort, HdmiCecSinkSuccess &success) override; + uint32_t SetupARCRouting(const bool enabled, HdmiCecSinkSuccess &success) override; + uint32_t SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) override; + uint32_t SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) override; + + private: + std::list _hdmiCecSinkNotifications; + }; + } // namespace Plugin +} // namespace WPEFramework + + + + From 7b2c0f661bed86537b944825aa71b0ac0a9d8750 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Wed, 16 Apr 2025 11:55:42 -0400 Subject: [PATCH 02/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 166 +++++++++++++++++----- HdmiCecSink/HdmiCecSinkImplementation.h | 7 + 2 files changed, 134 insertions(+), 39 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 0cee5ade..639ae090 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -688,6 +688,9 @@ namespace WPEFramework m_currentActiveSource = -1; m_isHdmiInConnected = false; hdmiCecAudioDeviceConnected = false; + m_isAudioStatusInfoUpdated = false; + m_audioStatusReceived = false; + m_audioStatusTimerStarted = false; m_audioDevicePowerStatusRequested = false; m_pollNextState = POLL_THREAD_STATE_NONE; m_pollThreadState = POLL_THREAD_STATE_NONE; @@ -697,6 +700,12 @@ namespace WPEFramework logicalAddressDeviceType = "None"; logicalAddress = 0xFF; + // load persistence setting + loadSettings(); + + int err; + dsHdmiInGetNumberOfInputsParam_t hdmiInput; + InitializeIARM(); m_sendKeyEventThreadExit = false; m_sendKeyEventThread = std::thread(threadSendKeyEvent); @@ -704,15 +713,11 @@ namespace WPEFramework m_semSignaltoArcRoutingThread.acquire(); m_arcRoutingThread = std::thread(threadArcRouting); - + m_audioStatusDetectionTimer.connect( std::bind( &HdmiCecSink::audioStatusTimerFunction, this ) ); + m_audioStatusDetectionTimer.setSingleShot(true); m_arcStartStopTimer.connect( std::bind( &HdmiCecSinkImplementation::arcStartStopTimerFunction, this ) ); m_arcStartStopTimer.setSingleShot(true); - // load persistence setting - loadSettings(); - int err; - dsHdmiInGetNumberOfInputsParam_t hdmiInput; - InitializeIARM(); // get power state: uint32_t res = Core::ERROR_GENERAL; PowerState pwrStateCur = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; @@ -764,8 +769,8 @@ namespace WPEFramework } } getCecVersion(); - getHdmiArcPortID(); - return (std::string()); + LOGINFO(" HdmiCecSink plugin Initialize completed \n"); + return (std::string()); } @@ -1092,6 +1097,18 @@ namespace WPEFramework { if(!HdmiCecSinkImplementation::_instance) return; + if (m_audioStatusTimerStarted) + { + m_audioStatusReceived = true; + m_isAudioStatusInfoUpdated = true; + m_audioStatusTimerStarted = false; + if (m_audioStatusDetectionTimer.isActive()) + { + LOGINFO("AudioStatus received from the Audio Device and the timer is still active. So stopping the timer!\n"); + m_audioStatusDetectionTimer.stop(); + } + LOGINFO("AudioStatus received from the Audio Device. Updating the AudioStatus info! m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); + } LOGINFO("Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n",GetOpName(msg.opCode()),msg.status.getAudioMuteStatus(),msg.status.toString().c_str(),msg.status.getAudioVolume()); while (index != _hdmiCecSourceNotifications.end()) { (*index)->ReportAudioStatusEvent(msg.status.getAudioMuteStatus(), msg.status.getAudioVolume()); @@ -2393,6 +2410,13 @@ namespace WPEFramework LOGINFO(" logicalAddress =%d , Audio device removed, Notify Device Settings", logicalAddress ); hdmiCecAudioDeviceConnected = false; + if (m_audioStatusDetectionTimer.isActive()){ + m_audioStatusDetectionTimer.stop(); + } + m_isAudioStatusInfoUpdated = false; + m_audioStatusReceived = false; + m_audioStatusTimerStarted = false; + LOGINFO("Audio device removed, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); while (index != _hdmiCecSourceNotifications.end()) { (*index)->ReportAudioDeviceConnectedStatus("success", "false"); index++; @@ -2642,29 +2666,44 @@ namespace WPEFramework _instance->allocateLogicalAddress(DeviceType::TV); if ( _instance->m_logicalAddressAllocated != LogicalAddress::UNREGISTERED) { - logicalAddress = LogicalAddress(_instance->m_logicalAddressAllocated); - LibCCEC::getInstance().addLogicalAddress(logicalAddress); - _instance->smConnection->setSource(logicalAddress); - _instance->m_numberOfDevices = 0; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType = DeviceType::TV; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_isDevicePresent = true; - _instance->deviceList[_instance->m_logicalAddressAllocated].update(physical_addr); - _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_1_4; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_vendorID = appVendorId; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus = PowerStatus(powerState); - _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage = defaultLanguage; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_osdName = osdName.toString().c_str(); - if(cecVersion == 2.0) { - _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_2_0; - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), - MessageEncoder().encode(ReportFeatures(Version::V_2_0,allDevicetype,rcProfile,deviceFeatures)), 500); + try{ + + logicalAddress = LogicalAddress(_instance->m_logicalAddressAllocated); + LibCCEC::getInstance().addLogicalAddress(logicalAddress); + _instance->smConnection->setSource(logicalAddress); + _instance->m_numberOfDevices = 0; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType = DeviceType::TV; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_isDevicePresent = true; + _instance->deviceList[_instance->m_logicalAddressAllocated].update(physical_addr); + _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_1_4; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_vendorID = appVendorId; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus = PowerStatus(powerState); + _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage = defaultLanguage; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_osdName = osdName.toString().c_str(); + if(cecVersion == 2.0) { + _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_2_0; + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), + MessageEncoder().encode(ReportFeatures(Version::V_2_0,allDevicetype,rcProfile,deviceFeatures)), 500); + } + _instance->smConnection->addFrameListener(_instance->msgFrameListener); + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), + MessageEncoder().encode(ReportPhysicalAddress(physical_addr, _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType)), 100); + + _instance->m_sleepTime = 0; + _instance->m_pollThreadState = POLL_THREAD_STATE_PING; + } + catch(InvalidStateException &e){ + LOGWARN("InvalidStateException caught while allocated logical address. %s", e.what()); + _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; + } + catch(IOException &e){ + LOGWARN("IOException caught while allocated logical address. %s", e.what()); + _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; + } + catch(...){ + LOGWARN("Exception caught while allocated logical address."); + _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; } - _instance->smConnection->addFrameListener(_instance->msgFrameListener); - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), - MessageEncoder().encode(ReportPhysicalAddress(physical_addr, _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType)), 100); - - _instance->m_sleepTime = 0; - _instance->m_pollThreadState = POLL_THREAD_STATE_PING; } else { @@ -2900,9 +2939,14 @@ namespace WPEFramework { LibCCEC::getInstance().init("HdmiCecSink"); } - catch (const std::exception& e) - { - LOGWARN("CEC exception caught from LibCCEC::getInstance().init()"); + catch(InvalidStateException &e){ + LOGWARN("InvalidStateException caught in LibCCEC::init %s", e.what()); + } + catch(IOException &e){ + LOGWARN("IOException caught in LibCCEC::init %s", e.what()); + } + catch(...){ + LOGWARN("Exception caught in LibCCEC::init"); } } libcecInitStatus++; @@ -2998,7 +3042,14 @@ namespace WPEFramework } m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; - m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + if (m_audioStatusDetectionTimer.isActive()){ + m_audioStatusDetectionTimer.stop(); + } + m_isAudioStatusInfoUpdated = false; + m_audioStatusReceived = false; + m_audioStatusTimerStarted = false; + LOGINFO("CEC Disabled, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); for(int i=0; i< 16; i++) { @@ -3014,10 +3065,14 @@ namespace WPEFramework { LibCCEC::getInstance().term(); } - catch (const std::exception& e) - { - LOGWARN("CEC exception caught from LibCCEC::getInstance().term() "); + catch(InvalidStateException &e){ + LOGWARN("InvalidStateException caught in LibCCEC::term %s", e.what()); } + catch(IOException &e){ + LOGWARN("IOException caught in LibCCEC::term %s", e.what()); + } + catch(...){ + LOGWARN("Exception caught in LibCCEC::term"); } libcecInitStatus--; @@ -3253,12 +3308,45 @@ namespace WPEFramework if((_instance->m_SendKeyQueue.size()<=1 || (_instance->m_SendKeyQueue.size() % 2 == 0)) && ((keyInfo.keyCode == VOLUME_UP) || (keyInfo.keyCode == VOLUME_DOWN) || (keyInfo.keyCode == MUTE)) ) { - _instance->sendGiveAudioStatusMsg(); + if(keyInfo.keyCode == MUTE) + { + _instance->sendGiveAudioStatusMsg(); + } + else + { + LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ",_instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); + if (!_instance->m_isAudioStatusInfoUpdated) + { + if ( !(_instance->m_audioStatusDetectionTimer.isActive())) + { + LOGINFO("Audio status info not updated. Starting the Timer!"); + _instance->m_audioStatusTimerStarted = true; + _instance->m_audioStatusDetectionTimer.start((HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS)); + } + LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", _instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); + } + else + { + if (!_instance->m_audioStatusReceived){ + _instance->sendGiveAudioStatusMsg(); + } + } + } + } } }//while(!_instance->m_sendKeyEventThreadExit) }//threadSendKeyEvent + void HdmiCecSinkImplementation::audioStatusTimerFunction() + { + m_audioStatusTimerStarted = false; + m_isAudioStatusInfoUpdated = true; + LOGINFO("Timer Expired. Requesting the AudioStatus since not received.\n"); + sendGiveAudioStatusMsg(); + LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); + } + void HdmiCecSinkImplementation::threadArcRouting() { @@ -3269,7 +3357,7 @@ namespace WPEFramework return; LOGINFO("Running threadArcRouting"); - + _instance->getHdmiArcPortID(); while(1) { diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 4a787a54..9448c4f2 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -576,6 +576,8 @@ namespace WPEFramework { void sendGiveAudioStatusMsg(); void onPowerModeChanged(const PowerState ¤tState, const PowerState &newState); void registerEventHandlers(); + void sendGiveAudioStatusMsg(); + void getHdmiArcPortID(); int m_numberOfDevices; /* Number of connected devices othethan own device */ bool m_audioDevicePowerStatusRequested; @@ -643,6 +645,9 @@ namespace WPEFramework { /* Send Key event related */ bool m_sendKeyEventThreadExit; bool m_sendKeyEventThreadRun; + bool m_isAudioStatusInfoUpdated; + bool m_audioStatusReceived; + bool m_audioStatusTimerStarted; std::thread m_sendKeyEventThread; std::mutex m_sendKeyEventMutex; std::queue m_SendKeyQueue; @@ -661,6 +666,7 @@ namespace WPEFramework { binary_semaphore m_semSignaltoArcRoutingThread; bool m_arcstarting; TpTimer m_arcStartStopTimer; + TpTimer m_audioStatusDetectionTimer; Connection *smConnection; std::vector m_connectedDevices; @@ -707,6 +713,7 @@ namespace WPEFramework { void Send_Request_Arc_Termination_Message(); void Send_Report_Arc_Terminated_Message(); void arcStartStopTimerFunction(); + void audioStatusTimerFunction(); void getHdmiArcPortID(); void getCecVersion(); From 44eecdeae3929d4e10729cbe894e361f059c2a8f Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Wed, 16 Apr 2025 11:59:10 -0400 Subject: [PATCH 03/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 639ae090..45c13a7d 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -46,6 +46,7 @@ #define HDMICECSINK_NUMBER_TV_ADDR 2 #define HDMICECSINK_UPDATE_POWER_STATUS_INTERVA_MS (60 * 1000) #define HDMISINK_ARC_START_STOP_MAX_WAIT_MS 4000 +#define HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS 500 #define SAD_FMT_CODE_AC3 2 From 6f389a089554de5a1f7efab886c2eb9282546253 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 21 Apr 2025 13:40:02 -0400 Subject: [PATCH 04/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 22 ++-------------------- HdmiCecSink/HdmiCecSink.h | 2 +- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 0c5c044c..372900ad 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -137,22 +137,10 @@ namespace WPEFramework SERVICE_REGISTRATION(HdmiCecSink, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); HdmiCecSink* HdmiCecSink::_instance = nullptr; - static int libcecInitStatus = 0; -//=========================================== HdmiCecSink ========================================= + //=========================================== HdmiCecSink ========================================= - HdmiCecSink::HdmiCecSink() - : PluginHost::JSONRPC() - , _pwrMgrNotification(*this) - , _registeredEventHandlers(false) - { - LOGWARN("Initlaizing HdmiCecSink"); - } - - HdmiCecSink::~HdmiCecSink() - { - } const std::string HdmiCecSink::Initialize(PluginHost::IShell *service) { profileType = searchRdkProfile(); @@ -202,12 +190,6 @@ namespace WPEFramework void HdmiCecSink::Deinitialize(PluginHost::IShell* /* service */) { - if(_powerManagerPlugin) - { - _powerManagerPlugin.Reset(); - } - _registeredEventHandlers = false; - profileType = searchRdkProfile(); if (profileType == STB || profileType == NOT_FOUND) @@ -216,7 +198,7 @@ namespace WPEFramework return ; } - CECDisable(); + HdmiCecSink::_hdmiCecSink->SetEnabled(false); if(nullptr != _hdmiCecSink) { diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index 84358a4a..e9f088d5 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -194,7 +194,7 @@ namespace WPEFramework { Exchange::JHdmiCecSink::Event::SetSystemAudioModeEvent(_parent, audioMode); } - void ShortAudiodescriptorEvent(IHdmiCecSinkShortAudioDescriptorIterator* ShortAudioDescriptor) override + void ShortAudiodescriptorEvent(Exchange::IHdmiCecSink::IHdmiCecSinkShortAudioDescriptorIterator* ShortAudioDescriptor) override { LOGINFO("ShortAudiodescriptorEvent"); Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, ShortAudioDescriptor); From 47cc33e595694e6a29537c0322b9d5281975fc55 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 21 Apr 2025 15:25:54 -0400 Subject: [PATCH 05/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 9 ++------- HdmiCecSink/HdmiCecSink.h | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 372900ad..79e6d5eb 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -134,12 +134,7 @@ namespace WPEFramework namespace Plugin { - SERVICE_REGISTRATION(HdmiCecSink, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); - - HdmiCecSink* HdmiCecSink::_instance = nullptr; - - - //=========================================== HdmiCecSink ========================================= + SERVICE_REGISTRATION(HdmiCecSink, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); const std::string HdmiCecSink::Initialize(PluginHost::IShell *service) { @@ -198,7 +193,7 @@ namespace WPEFramework return ; } - HdmiCecSink::_hdmiCecSink->SetEnabled(false); + HdmiCecSink::_hdmiCecSink->SetEnabled(false,success); if(nullptr != _hdmiCecSink) { diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index e9f088d5..dc62c8aa 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -194,7 +194,7 @@ namespace WPEFramework { Exchange::JHdmiCecSink::Event::SetSystemAudioModeEvent(_parent, audioMode); } - void ShortAudiodescriptorEvent(Exchange::IHdmiCecSink::IHdmiCecSinkShortAudioDescriptorIterator* ShortAudioDescriptor) override + void ShortAudiodescriptorEvent(Exchange::IHdmiCecSink::IHdmiCecSinkShortAudioDescriptorIterator* const& ShortAudioDescriptor) override { LOGINFO("ShortAudiodescriptorEvent"); Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, ShortAudioDescriptor); From 11b35c0f19b8c7efc6d8b9001ab77d2e233eb82d Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 22 Apr 2025 10:04:11 -0400 Subject: [PATCH 06/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 86 +------------------------------------ HdmiCecSink/HdmiCecSink.h | 2 +- 2 files changed, 3 insertions(+), 85 deletions(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 79e6d5eb..4954c7af 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -19,98 +19,14 @@ #include "HdmiCecSink.h" -#include "ccec/Connection.hpp" -#include "ccec/CECFrame.hpp" -#include "ccec/MessageEncoder.hpp" -#include "host.hpp" -#include "UtilsgetRFCConfig.h" - -#include "dsMgr.h" -#include "dsRpc.h" -#include "dsDisplay.h" -#include "videoOutputPort.hpp" -#include "manager.hpp" -#include "websocket/URL.h" - #include "UtilsIarm.h" #include "UtilsJsonRpc.h" #include "UtilssyncPersistFile.h" #include "UtilsSearchRDKProfile.h" -#define HDMICECSINK_METHOD_SET_ENABLED "setEnabled" -#define HDMICECSINK_METHOD_GET_ENABLED "getEnabled" -#define HDMICECSINK_METHOD_OTP_SET_ENABLED "setOTPEnabled" -#define HDMICECSINK_METHOD_OTP_GET_ENABLED "getOTPEnabled" -#define HDMICECSINK_METHOD_SET_OSD_NAME "setOSDName" -#define HDMICECSINK_METHOD_GET_OSD_NAME "getOSDName" -#define HDMICECSINK_METHOD_SET_VENDOR_ID "setVendorId" -#define HDMICECSINK_METHOD_GET_VENDOR_ID "getVendorId" -#define HDMICECSINK_METHOD_PRINT_DEVICE_LIST "printDeviceList" -#define HDMICECSINK_METHOD_SET_ACTIVE_PATH "setActivePath" -#define HDMICECSINK_METHOD_SET_ROUTING_CHANGE "setRoutingChange" -#define HDMICECSINK_METHOD_GET_DEVICE_LIST "getDeviceList" -#define HDMICECSINK_METHOD_GET_ACTIVE_SOURCE "getActiveSource" -#define HDMICECSINK_METHOD_SET_ACTIVE_SOURCE "setActiveSource" -#define HDMICECSINK_METHOD_GET_ACTIVE_ROUTE "getActiveRoute" -#define HDMICECSINK_METHOD_SET_MENU_LANGUAGE "setMenuLanguage" -#define HDMICECSINK_METHOD_REQUEST_ACTIVE_SOURCE "requestActiveSource" -#define HDMICECSINK_METHOD_SETUP_ARC "setupARCRouting" -#define HDMICECSINK_METHOD_REQUEST_SHORT_AUDIO_DESCRIPTOR "requestShortAudioDescriptor" -#define HDMICECSINK_METHOD_SEND_STANDBY_MESSAGE "sendStandbyMessage" -#define HDMICECSINK_METHOD_SEND_AUDIO_DEVICE_POWER_ON "sendAudioDevicePowerOnMessage" -#define HDMICECSINK_METHOD_SEND_KEY_PRESS "sendKeyPressEvent" -#define HDMICECSINK_METHOD_SEND_USER_CONTROL_PRESSED "sendUserControlPressed" -#define HDMICECSINK_METHOD_SEND_USER_CONTROL_RELEASED "sendUserControlReleased" -#define HDMICECSINK_METHOD_SEND_GIVE_AUDIO_STATUS "sendGetAudioStatusMessage" -#define HDMICECSINK_METHOD_GET_AUDIO_DEVICE_CONNECTED_STATUS "getAudioDeviceConnectedStatus" -#define HDMICECSINK_METHOD_REQUEST_AUDIO_DEVICE_POWER_STATUS "requestAudioDevicePowerStatus" -#define HDMICECSINK_METHOD_SET_LATENCY_INFO "setLatencyInfo" - -#define TEST_ADD 0 -#define HDMICECSINK_REQUEST_MAX_RETRY 3 -#define HDMICECSINK_REQUEST_MAX_WAIT_TIME_MS 2000 -#define HDMICECSINK_PING_INTERVAL_MS 10000 -#define HDMICECSINK_WAIT_FOR_HDMI_IN_MS 1000 -#define HDMICECSINK_REQUEST_INTERVAL_TIME_MS 500 -#define HDMICECSINK_NUMBER_TV_ADDR 2 -#define HDMICECSINK_UPDATE_POWER_STATUS_INTERVA_MS (60 * 1000) -#define HDMISINK_ARC_START_STOP_MAX_WAIT_MS 4000 -#define HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS 500 - - -#define SAD_FMT_CODE_AC3 2 -#define SAD_FMT_CODE_ENHANCED_AC3 10 - -#define SYSTEM_AUDIO_MODE_ON 0x01 -#define SYSTEM_AUDIO_MODE_OFF 0x00 -#define AUDIO_DEVICE_POWERSTATE_OFF 1 - -#define DEFAULT_VIDEO_LATENCY 100 -#define DEFAULT_LATENCY_FLAGS 3 -#define DEFAULT_AUDIO_OUTPUT_DELAY 100 - -//Device Type is TV - Bit 7 is set to 1 -#define ALL_DEVICE_TYPES 128 - -//RC Profile of TV is 3 - Typical TV Remote -#define RC_PROFILE_TV 10 - -//Device Features supported by TV - ARC Tx -#define DEVICE_FEATURES_TV 4 #define TR181_HDMICECSINK_CEC_VERSION "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.HdmiCecSink.CECVersion" -enum { - DEVICE_POWER_STATE_ON = 0, - DEVICE_POWER_STATE_OFF = 1 -}; - - -#define CEC_SETTING_ENABLED_FILE "/opt/persistent/ds/cecData_2.json" -#define CEC_SETTING_OTP_ENABLED "cecOTPEnabled" -#define CEC_SETTING_ENABLED "cecEnabled" -#define CEC_SETTING_OSD_NAME "cecOSDName" -#define CEC_SETTING_VENDOR_ID "cecVendorId" #define API_VERSION_NUMBER_MAJOR 1 #define API_VERSION_NUMBER_MINOR 3 @@ -193,6 +109,8 @@ namespace WPEFramework return ; } + bool success = false; + HdmiCecSink::_hdmiCecSink->SetEnabled(false,success); if(nullptr != _hdmiCecSink) diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index dc62c8aa..d3928a83 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -197,7 +197,7 @@ namespace WPEFramework { void ShortAudiodescriptorEvent(Exchange::IHdmiCecSink::IHdmiCecSinkShortAudioDescriptorIterator* const& ShortAudioDescriptor) override { LOGINFO("ShortAudiodescriptorEvent"); - Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, ShortAudioDescriptor); + Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, &ShortAudioDescriptor); } void StandbyMessageReceived(const int logicalAddress) override From 7b03d519b38a920b59d666ed59ca8796e664b98c Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:39:04 -0400 Subject: [PATCH 07/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 4954c7af..22bfc93e 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -109,7 +109,7 @@ namespace WPEFramework return ; } - bool success = false; + Exchange::IHdmiCecSink::HdmiCecSinkSuccess success = false; HdmiCecSink::_hdmiCecSink->SetEnabled(false,success); From 7f8dd89ee89802f2ac8087bd99895583354bae0d Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 22 Apr 2025 12:17:58 -0400 Subject: [PATCH 08/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 22bfc93e..750ddda1 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -109,7 +109,7 @@ namespace WPEFramework return ; } - Exchange::IHdmiCecSink::HdmiCecSinkSuccess success = false; + Exchange::IHdmiCecSink::HdmiCecSinkSuccess success; HdmiCecSink::_hdmiCecSink->SetEnabled(false,success); From 97414bc34aea7c05e7bb3d24b4167eb27b1e5cc6 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Thu, 24 Apr 2025 15:23:20 -0400 Subject: [PATCH 09/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.h | 2 +- HdmiCecSink/HdmiCecSinkImplementation.cpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index d3928a83..d231569f 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -194,7 +194,7 @@ namespace WPEFramework { Exchange::JHdmiCecSink::Event::SetSystemAudioModeEvent(_parent, audioMode); } - void ShortAudiodescriptorEvent(Exchange::IHdmiCecSink::IHdmiCecSinkShortAudioDescriptorIterator* const& ShortAudioDescriptor) override + void ShortAudiodescriptorEvent(IValueIterator* const& ShortAudioDescriptor) override { LOGINFO("ShortAudiodescriptorEvent"); Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, &ShortAudioDescriptor); diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 45c13a7d..5c3081cb 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -994,15 +994,14 @@ namespace WPEFramework { LOGINFO("Notify the DS "); - std::vector shortAudioDescriptors; - for (size_t i = 0; i < audiodescriptor.Length(); i++) { - shortAudioDescriptors.push_back(audiodescriptor[i].Number()); - } + - while (index != _hdmiCecSourceNotifications.end()) { - (*index)->ShortAudioDescriptorEvent(shortAudioDescriptors); - index++; - } + + + //while (index != _hdmiCecSourceNotifications.end()) { + // (*index)->ShortAudioDescriptorEvent(shortAudioDescriptors); + // index++; + //} } void HdmiCecSinkImplementation::Process_ShortAudioDescriptor_msg(const ReportShortAudioDescriptor &msg) From fb090da6f490a153b42ed4b42934fdda96155287 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 19 May 2025 14:16:50 -0400 Subject: [PATCH 10/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 160 ++++++++++-------------------------- HdmiCecSink/HdmiCecSink.h | 2 +- 2 files changed, 43 insertions(+), 119 deletions(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 68fd7950..2943b43c 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -62,124 +62,41 @@ namespace WPEFramework return (std::string("Not supported")); } - HdmiCecSink::_instance = this; - smConnection=NULL; - cecEnableStatus = false; - HdmiCecSink::_instance->m_numberOfDevices = 0; - m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; - m_currentActiveSource = -1; - m_isHdmiInConnected = false; - hdmiCecAudioDeviceConnected = false; - m_isAudioStatusInfoUpdated = false; - m_audioStatusReceived = false; - m_audioStatusTimerStarted = false; - m_audioDevicePowerStatusRequested = false; - m_pollNextState = POLL_THREAD_STATE_NONE; - m_pollThreadState = POLL_THREAD_STATE_NONE; - m_video_latency = DEFAULT_VIDEO_LATENCY; - m_latency_flags = DEFAULT_LATENCY_FLAGS ; - m_audio_output_delay = DEFAULT_AUDIO_OUTPUT_DELAY; - - Register(HDMICECSINK_METHOD_SET_ENABLED, &HdmiCecSink::setEnabledWrapper, this); - Register(HDMICECSINK_METHOD_GET_ENABLED, &HdmiCecSink::getEnabledWrapper, this); - Register(HDMICECSINK_METHOD_SET_OSD_NAME, &HdmiCecSink::setOSDNameWrapper, this); - Register(HDMICECSINK_METHOD_GET_OSD_NAME, &HdmiCecSink::getOSDNameWrapper, this); - Register(HDMICECSINK_METHOD_SET_VENDOR_ID, &HdmiCecSink::setVendorIdWrapper, this); - Register(HDMICECSINK_METHOD_GET_VENDOR_ID, &HdmiCecSink::getVendorIdWrapper, this); - Register(HDMICECSINK_METHOD_PRINT_DEVICE_LIST, &HdmiCecSink::printDeviceListWrapper, this); - Register(HDMICECSINK_METHOD_SET_ACTIVE_PATH, &HdmiCecSink::setActivePathWrapper, this); - Register(HDMICECSINK_METHOD_SET_ROUTING_CHANGE, &HdmiCecSink::setRoutingChangeWrapper, this); - Register(HDMICECSINK_METHOD_GET_DEVICE_LIST, &HdmiCecSink::getDeviceListWrapper, this); - Register(HDMICECSINK_METHOD_GET_ACTIVE_SOURCE, &HdmiCecSink::getActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_SET_ACTIVE_SOURCE, &HdmiCecSink::setActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_GET_ACTIVE_ROUTE, &HdmiCecSink::getActiveRouteWrapper, this); - Register(HDMICECSINK_METHOD_REQUEST_ACTIVE_SOURCE, &HdmiCecSink::requestActiveSourceWrapper, this); - Register(HDMICECSINK_METHOD_SETUP_ARC, &HdmiCecSink::setArcEnableDisableWrapper, this); - Register(HDMICECSINK_METHOD_SET_MENU_LANGUAGE, &HdmiCecSink::setMenuLanguageWrapper, this); - Register(HDMICECSINK_METHOD_REQUEST_SHORT_AUDIO_DESCRIPTOR, &HdmiCecSink::requestShortAudioDescriptorWrapper, this); - Register(HDMICECSINK_METHOD_SEND_STANDBY_MESSAGE, &HdmiCecSink::sendStandbyMessageWrapper, this); - Register(HDMICECSINK_METHOD_SEND_AUDIO_DEVICE_POWER_ON, &HdmiCecSink::sendAudioDevicePowerOnMsgWrapper, this); - Register(HDMICECSINK_METHOD_SEND_KEY_PRESS,&HdmiCecSink::sendRemoteKeyPressWrapper,this); - Register(HDMICECSINK_METHOD_SEND_USER_CONTROL_PRESSED,&HdmiCecSink::sendUserControlPressedWrapper,this); - Register(HDMICECSINK_METHOD_SEND_USER_CONTROL_RELEASED,&HdmiCecSink::sendUserControlReleasedWrapper,this); - Register(HDMICECSINK_METHOD_SEND_GIVE_AUDIO_STATUS,&HdmiCecSink::sendGiveAudioStatusWrapper,this); - Register(HDMICECSINK_METHOD_GET_AUDIO_DEVICE_CONNECTED_STATUS,&HdmiCecSink::getAudioDeviceConnectedStatusWrapper,this); - Register(HDMICECSINK_METHOD_REQUEST_AUDIO_DEVICE_POWER_STATUS,&HdmiCecSink::requestAudioDevicePowerStatusWrapper,this); - Register(HDMICECSINK_METHOD_SET_LATENCY_INFO, &HdmiCecSink::setLatencyInfoWrapper, this); - logicalAddressDeviceType = "None"; - logicalAddress = 0xFF; - // load persistence setting - loadSettings(); - - int err; - dsHdmiInGetNumberOfInputsParam_t hdmiInput; - InitializeIARM(); - m_sendKeyEventThreadExit = false; - m_sendKeyEventThread = std::thread(threadSendKeyEvent); - - m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; - m_semSignaltoArcRoutingThread.acquire(); - m_arcRoutingThread = std::thread(threadArcRouting); - - m_audioStatusDetectionTimer.connect( std::bind( &HdmiCecSink::audioStatusTimerFunction, this ) ); - m_audioStatusDetectionTimer.setSingleShot(true); - m_arcStartStopTimer.connect( std::bind( &HdmiCecSink::arcStartStopTimerFunction, this ) ); - m_arcStartStopTimer.setSingleShot(true); - // get power state: - uint32_t res = Core::ERROR_GENERAL; - PowerState pwrStateCur = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; - PowerState pwrStatePrev = WPEFramework::Exchange::IPowerManager::POWER_STATE_UNKNOWN; - - ASSERT (_powerManagerPlugin); - if (_powerManagerPlugin) { - res = _powerManagerPlugin->GetPowerState(pwrStateCur, pwrStatePrev); - if (Core::ERROR_NONE == res) { - powerState = (pwrStateCur == WPEFramework::Exchange::IPowerManager::POWER_STATE_ON) ? DEVICE_POWER_STATE_ON : DEVICE_POWER_STATE_OFF; - LOGINFO("Current state is PowerManagerPlugin: (%d) powerState :%d \n", pwrStateCur, powerState); - } - } + string msg = ""; - err = IARM_Bus_Call(IARM_BUS_DSMGR_NAME, - IARM_BUS_DSMGR_API_dsHdmiInGetNumberOfInputs, - (void *)&hdmiInput, - sizeof(hdmiInput)); - - if (err == IARM_RESULT_SUCCESS && hdmiInput.result == dsERR_NONE) - { - LOGINFO("Number of Inputs [%d] \n", hdmiInput.numHdmiInputs ); - m_numofHdmiInput = hdmiInput.numHdmiInputs; - }else{ - LOGINFO("Not able to get Numebr of inputs so defaulting to 3 \n"); - m_numofHdmiInput = 3; - } + ASSERT(nullptr != service); + ASSERT(nullptr == _service); + ASSERT(nullptr == _hdmiCecSink); + ASSERT(0 == _connectionId); - LOGINFO("initalize inputs \n"); - for (int i = 0; i < m_numofHdmiInput; i++){ - HdmiPortMap hdmiPort((uint8_t)i); - LOGINFO(" Add to vector [%d] \n", i); - hdmiInputs.push_back(hdmiPort); - } + _service = service; + _service->AddRef(); + _service->Register(&_notification); + _hdmiCecSink = _service->Root(_connectionId, 5000, _T("HdmiCecSinkImplementation")); - LOGINFO("Check the HDMI State \n"); + if(nullptr != _hdmiCecSink) + { + _hdmiCecSink->Configure(service); + _hdmiCecSink->Register(&_notification); + Exchange::JHdmiCecSink::Register(*this, _hdmiCecSink); + LOGINFO("HdmiCecSink plugin is available. Successfully activated HdmiCecSink Plugin"); + } + else + { + msg = "HdmiCecSink plugin is not available"; + LOGINFO("HdmiCecSink plugin is not available. Failed to activate HdmiCecSink Plugin"); + } - CheckHdmiInState(); - if (cecSettingEnabled) + if (0 != msg.length()) { - try - { - CECEnable(); - } - catch(...) - { - LOGWARN("Exception while enabling CEC settings .\r\n"); - } + Deinitialize(service); } - getCecVersion(); - LOGINFO(" HdmiCecSink plugin Initialize completed \n"); - return (std::string()); - } + // On success return empty, to indicate there is no error text. + return msg; + } + void HdmiCecSink::Deinitialize(PluginHost::IShell* /* service */) { @@ -191,11 +108,18 @@ namespace WPEFramework return ; } - Exchange::IHdmiCecSink::HdmiCecSinkSuccess success; + bool enabled = false; + bool ret = false; + HdmiCecSink::_hdmiCecSink->GetEnabled(enabled,ret); - HdmiCecSink::_hdmiCecSink->SetEnabled(false,success); + if(ret && enabled) + { + Exchange::IHdmiCecSink::HdmiCecSinkSuccess success; + HdmiCecSink::_hdmiCecSink->SetEnabled(false,success); + } + HdmiCecSink::_notification.OnActiveSourceStatusUpdated(false); - if(nullptr != _hdmiCecSink) + if(nullptr != _hdmiCecSink) { _hdmiCecSink->Unregister(&_notification); Exchange::JHdmiCecSink::Unregister(*this); @@ -219,11 +143,11 @@ namespace WPEFramework } } - _connectionId = 0; - _service->Release(); - _service = nullptr; - LOGWARN(" HdmiCecSink Deinitialize() Done"); - } + _connectionId = 0; + _service->Release(); + _service = nullptr; + LOGINFO("HdmiCecSink plugin is deactivated. Successfully deactivated HdmiCecSink Plugin"); + } string HdmiCecSink::Information() const { diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index d231569f..d6f73840 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -194,7 +194,7 @@ namespace WPEFramework { Exchange::JHdmiCecSink::Event::SetSystemAudioModeEvent(_parent, audioMode); } - void ShortAudiodescriptorEvent(IValueIterator* const& ShortAudioDescriptor) override + void ShortAudiodescriptorEvent(IHdmiCecSinkShortAudioDescriptorIterator* const& ShortAudioDescriptor) override { LOGINFO("ShortAudiodescriptorEvent"); Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, &ShortAudioDescriptor); From ea4a12de947b6498ef3230a9a18c31ab0c285fdc Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Thu, 22 May 2025 12:35:15 -0400 Subject: [PATCH 11/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 2943b43c..6422e51f 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -117,7 +117,6 @@ namespace WPEFramework Exchange::IHdmiCecSink::HdmiCecSinkSuccess success; HdmiCecSink::_hdmiCecSink->SetEnabled(false,success); } - HdmiCecSink::_notification.OnActiveSourceStatusUpdated(false); if(nullptr != _hdmiCecSink) { From 7974449b24c3415ac9fdfd0d0d130cbe088a7c96 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 27 May 2025 10:14:57 -0400 Subject: [PATCH 12/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.h | 4 ++-- HdmiCecSink/HdmiCecSinkImplementation.cpp | 16 +++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index d6f73840..50bbca71 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -194,10 +194,10 @@ namespace WPEFramework { Exchange::JHdmiCecSink::Event::SetSystemAudioModeEvent(_parent, audioMode); } - void ShortAudiodescriptorEvent(IHdmiCecSinkShortAudioDescriptorIterator* const& ShortAudioDescriptor) override + void ShortAudiodescriptorEvent(const string& jsonresponse) override { LOGINFO("ShortAudiodescriptorEvent"); - Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, &ShortAudioDescriptor); + Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, &jsonresponse); } void StandbyMessageReceived(const int logicalAddress) override diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 5c3081cb..26a51a21 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -994,14 +994,16 @@ namespace WPEFramework { LOGINFO("Notify the DS "); - - + string shortAudioDescriptors; - - //while (index != _hdmiCecSourceNotifications.end()) { - // (*index)->ShortAudioDescriptorEvent(shortAudioDescriptors); - // index++; - //} + if (!audiodescriptor.ToString(shortAudioDescriptors)) { + LOGERR("Failed to stringify JsonArray"); + } + + while (index != _hdmiCecSourceNotifications.end()) { + (*index)->ShortAudioDescriptorEvent(shortAudioDescriptors); + index++; + } } void HdmiCecSinkImplementation::Process_ShortAudioDescriptor_msg(const ReportShortAudioDescriptor &msg) From 56e8cd9973171295f82c824a73666804332c49c0 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 27 May 2025 11:49:55 -0400 Subject: [PATCH 13/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 9 ++------- HdmiCecSink/HdmiCecSinkImplementation.cpp | 3 ++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index 1b69eda1..edb90f90 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -100,13 +100,7 @@ namespace WPEFramework void HdmiCecSink::Deinitialize(PluginHost::IShell* /* service */) { - if(_powerManagerPlugin) - { - _powerManagerPlugin->Unregister(_pwrMgrNotification.baseInterface()); - _powerManagerPlugin.Reset(); - } - _registeredEventHandlers = false; - + profileType = searchRdkProfile(); if (profileType == STB || profileType == NOT_FOUND) @@ -150,6 +144,7 @@ namespace WPEFramework } _connectionId = 0; + _service->Unregister(&_notification); _service->Release(); _service = nullptr; LOGINFO("HdmiCecSink plugin is deactivated. Successfully deactivated HdmiCecSink Plugin"); diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 26a51a21..22318089 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -615,7 +615,8 @@ namespace WPEFramework { if(_powerManagerPlugin) { - _powerManagerPlugin.Reset(); + _powerManagerPlugin->Unregister(_pwrMgrNotification.baseInterface()); + _powerManagerPlugin.Reset(); } _registeredEventHandlers = false; From 5006c0fa97e6927d944786ea98d5b2e9867f779f Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 27 May 2025 12:00:36 -0400 Subject: [PATCH 14/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSink.h b/HdmiCecSink/HdmiCecSink.h index 50bbca71..e0f61176 100644 --- a/HdmiCecSink/HdmiCecSink.h +++ b/HdmiCecSink/HdmiCecSink.h @@ -197,7 +197,7 @@ namespace WPEFramework { void ShortAudiodescriptorEvent(const string& jsonresponse) override { LOGINFO("ShortAudiodescriptorEvent"); - Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, &jsonresponse); + Exchange::JHdmiCecSink::Event::ShortAudiodescriptorEvent(_parent, jsonresponse); } void StandbyMessageReceived(const int logicalAddress) override From 97134d09ed1efed0625baab4e14d28bd1fd3b2b5 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Wed, 28 May 2025 15:15:59 -0400 Subject: [PATCH 15/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- Tests/L1Tests/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Tests/L1Tests/CMakeLists.txt b/Tests/L1Tests/CMakeLists.txt index 33773882..c20d64de 100755 --- a/Tests/L1Tests/CMakeLists.txt +++ b/Tests/L1Tests/CMakeLists.txt @@ -122,8 +122,10 @@ add_plugin_test_ex(PLUGIN_HDMIINPUT tests/test_HdmiInput.cpp "${HDMIINPUT_INC}" add_plugin_test_ex(PLUGIN_HDMICEC2 tests/test_HdmiCec2.cpp "../../HdmiCec_2" "${NAMESPACE}HdmiCec_2") # PLUGIN_HDMICECSINK -set (HDMICECSINK_INC ${CMAKE_SOURCE_DIR}/../entservices-inputoutput/HdmiCecSink ${CMAKE_SOURCE_DIR}/../entservices-inputoutput/helpers) -add_plugin_test_ex(PLUGIN_HDMICECSINK tests/test_HdmiCecSink.cpp "${HDMICECSINK_INC}" "${NAMESPACE}HdmiCecSink") +set (HDMICECSINK_INC ${CMAKE_SINK_DIR}/../entservices-inputoutput/HdmiCecSink ${CMAKE_SINK_DIR}/../entservices-inputoutput/helpers) +set (HDMICECSINK_LIBS ${NAMESPACE}HdmiCecSink ${NAMESPACE}HdmiCecSinkImplementation) +add_plugin_test_ex(PLUGIN_HDMICECSINK tests/test_HdmiCecSink.cpp "${HDMICECSINK_INC}" "${HDMICECSINK_LIBS}") + # PLUGIN_HDMICECSOURCE set (HDMICECSOURCE_INC ${CMAKE_SOURCE_DIR}/../entservices-inputoutput/HdmiCecSource ${CMAKE_SOURCE_DIR}/../entservices-inputoutput/helpers) From 79990e251eb67bef3e47e00dee6ac0d2a54ae88c Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Fri, 30 May 2025 10:21:11 -0400 Subject: [PATCH 16/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/CMakeLists.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/HdmiCecSink/CMakeLists.txt b/HdmiCecSink/CMakeLists.txt index b244641e..11e12e6f 100644 --- a/HdmiCecSink/CMakeLists.txt +++ b/HdmiCecSink/CMakeLists.txt @@ -16,6 +16,7 @@ # limitations under the License. set(PLUGIN_NAME HdmiCecSink) set(MODULE_NAME ${NAMESPACE}${PLUGIN_NAME}) +set(PLUGIN_IMPLEMENTATION ${MODULE_NAME}Implementation) set(PLUGIN_HDMICECSINK_STARTUPORDER "" CACHE STRING "To configure startup order of HdmiCecSink plugin") @@ -26,10 +27,18 @@ add_library(${MODULE_NAME} SHARED HdmiCecSink.cpp Module.cpp) +add_library(${PLUGIN_IMPLEMENTATION} SHARED + HdmiCecSinkImplementation.cpp + Module.cpp) + set_target_properties(${MODULE_NAME} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES) +set_target_properties(${PLUGIN_IMPLEMENTATION} PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES) + target_compile_definitions(${MODULE_NAME} PRIVATE MODULE_NAME=Plugin_${PLUGIN_NAME}) find_package(DS) @@ -41,13 +50,23 @@ target_include_directories(${MODULE_NAME} PRIVATE ${CEC_INCLUDE_DIRS}) target_include_directories(${MODULE_NAME} PRIVATE ${DS_INCLUDE_DIRS}) set_source_files_properties(HdmiCecSink.cpp PROPERTIES COMPILE_FLAGS "-fexceptions") + +target_include_directories(${PLUGIN_IMPLEMENTATION} PRIVATE ${IARMBUS_INCLUDE_DIRS} ../helpers) +target_include_directories(${PLUGIN_IMPLEMENTATION} PRIVATE ${CEC_INCLUDE_DIRS}) +target_include_directories(${PLUGIN_IMPLEMENTATION} PRIVATE ${DS_INCLUDE_DIRS}) +set_source_files_properties(HdmiCecSinkImplementation.cpp PROPERTIES COMPILE_FLAGS "-fexceptions") + target_link_libraries(${MODULE_NAME} PUBLIC ${NAMESPACE}Plugins::${NAMESPACE}Plugins ${IARMBUS_LIBRARIES} ${CEC_LIBRARIES} ${DS_LIBRARIES} ) +target_link_libraries(${PLUGIN_IMPLEMENTATION} PUBLIC ${NAMESPACE}Plugins::${NAMESPACE}Plugins ${IARMBUS_LIBRARIES} ${CEC_LIBRARIES} ${DS_LIBRARIES} ) if (NOT RDK_SERVICES_L1_TEST) - target_compile_options(${MODULE_NAME} PRIVATE -Wno-error=deprecated) + target_compile_options(${PLUGIN_IMPLEMENTATION} PRIVATE -Wno-error=deprecated) endif () install(TARGETS ${MODULE_NAME} DESTINATION lib/${STORAGE_DIRECTORY}/plugins) +install(TARGETS ${PLUGIN_IMPLEMENTATION} + DESTINATION lib/${STORAGE_DIRECTORY}/plugins) + write_config(${PLUGIN_NAME}) From 6e704d872b0ce03760d2a66f7e7dbd66d8267f19 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Fri, 30 May 2025 16:13:58 -0400 Subject: [PATCH 17/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 31 +++++++---------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 22318089..cfc2e9b0 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -103,25 +103,12 @@ using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; namespace WPEFramework { - namespace { - - static Plugin::Metadata metadata( - // Version (Major, Minor, Patch) - API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH, - // Preconditions - {}, - // Terminations - {}, - // Controls - {} - ); - } namespace Plugin { - SERVICE_REGISTRATION(HdmiCecSink, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); + SERVICE_REGISTRATION(HdmiCecSinkImplementation, API_VERSION_NUMBER_MAJOR, API_VERSION_NUMBER_MINOR, API_VERSION_NUMBER_PATCH); - HdmiCecSink* HdmiCecSinkImplementation::_instance = nullptr; + HdmiCecSinkImplementation* HdmiCecSinkImplementation::_instance = nullptr; static int libcecInitStatus = 0; //=========================================== HdmiCecSinkFrameListener ========================================= @@ -601,17 +588,17 @@ namespace WPEFramework return; } } -//=========================================== HdmiCecSink ========================================= +//=========================================== HdmiCecSinkImplementation ========================================= - HdmiCecSinkImplementation::HdmiCecSink() + HdmiCecSinkImplementation::HdmiCecSinkImplementation() : PluginHost::JSONRPC() , _pwrMgrNotification(*this) , _registeredEventHandlers(false) { - LOGWARN("Initlaizing HdmiCecSink"); + LOGWARN("Initlaizing HdmiCecSinkImplementation"); } - HdmiCecSinkImplementation::~HdmiCecSink() + HdmiCecSinkImplementation::~HdmiCecSinkImplementation() { if(_powerManagerPlugin) { @@ -715,7 +702,7 @@ namespace WPEFramework m_semSignaltoArcRoutingThread.acquire(); m_arcRoutingThread = std::thread(threadArcRouting); - m_audioStatusDetectionTimer.connect( std::bind( &HdmiCecSink::audioStatusTimerFunction, this ) ); + m_audioStatusDetectionTimer.connect( std::bind( &HdmiCecSinkImplementation::audioStatusTimerFunction, this ) ); m_audioStatusDetectionTimer.setSingleShot(true); m_arcStartStopTimer.connect( std::bind( &HdmiCecSinkImplementation::arcStartStopTimerFunction, this ) ); m_arcStartStopTimer.setSingleShot(true); @@ -771,7 +758,7 @@ namespace WPEFramework } } getCecVersion(); - LOGINFO(" HdmiCecSink plugin Initialize completed \n"); + LOGINFO(" HdmiCecSinkImplementation plugin Initialize completed \n"); return (std::string()); } @@ -2940,7 +2927,7 @@ namespace WPEFramework { try { - LibCCEC::getInstance().init("HdmiCecSink"); + LibCCEC::getInstance().init("HdmiCecSinkImplementation"); } catch(InvalidStateException &e){ LOGWARN("InvalidStateException caught in LibCCEC::init %s", e.what()); From 5ded86e22440735f7277154daadd429babf8f076 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 09:22:09 -0400 Subject: [PATCH 18/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 9448c4f2..bf9faf9d 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -41,6 +41,7 @@ #include "UtilsLogging.h" #include #include "PowerManagerInterface.h" +#include "" using namespace WPEFramework; using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; @@ -576,7 +577,6 @@ namespace WPEFramework { void sendGiveAudioStatusMsg(); void onPowerModeChanged(const PowerState ¤tState, const PowerState &newState); void registerEventHandlers(); - void sendGiveAudioStatusMsg(); void getHdmiArcPortID(); int m_numberOfDevices; /* Number of connected devices othethan own device */ bool m_audioDevicePowerStatusRequested; @@ -714,7 +714,6 @@ namespace WPEFramework { void Send_Report_Arc_Terminated_Message(); void arcStartStopTimerFunction(); void audioStatusTimerFunction(); - void getHdmiArcPortID(); void getCecVersion(); From ad91b5acaf55402abe91e1dbb1ae0a4d91e22490 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 09:32:32 -0400 Subject: [PATCH 19/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index bf9faf9d..f50a6c00 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -41,7 +41,7 @@ #include "UtilsLogging.h" #include #include "PowerManagerInterface.h" -#include "" +#include using namespace WPEFramework; using PowerState = WPEFramework::Exchange::IPowerManager::PowerState; From 2a3b150b6dc983f56bd1021d8fd1c7b117627099 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 09:38:30 -0400 Subject: [PATCH 20/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.h | 51 +++++++++++++------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index f50a6c00..5fcc2c9d 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -718,30 +718,33 @@ namespace WPEFramework { public: - uint32_t GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute bool &success) override; - uint32_t GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) override; - uint32_t GetAudioDeviceConnectedStatus(bool &connected, bool &success) override; - uint32_t GetDeviceList(uint32_t &numberofdevices, IHdmiCecSinkDeviceListIterator*& deviceList, bool &success) override; - uint32_t GetEnabled(bool &enabled, bool &success) override; - uint32_t GetOSDName(string &name, bool &success) override; - uint32_t GetVendorId(string &vendorid, bool &success) override; - uint32_t PrintDeviceList(bool &printed, bool &success) override; - uint32_t RequestActiveSource(HdmiCecSinkSuccess &success) override; - uint32_t RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) override; - uint32_t SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) override; - uint32_t SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) override; - uint32_t SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; - uint32_t SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; - uint32_t SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) override; - uint32_t SendStandbyMessage(HdmiCecSinkSuccess &success) override; - uint32_t SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) override; - uint32_t SetActiveSource(HdmiCecSinkSuccess &success) override; - uint32_t SetEnabled(const bool enabled, HdmiCecSinkSuccess &success) override; - uint32_t SetOSDName(const string &name, HdmiCecSinkSuccess &success) override; - uint32_t SetRoutingChange(const string &oldPort, const string &newPort, HdmiCecSinkSuccess &success) override; - uint32_t SetupARCRouting(const bool enabled, HdmiCecSinkSuccess &success) override; - uint32_t SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) override; - uint32_t SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) override; + Core::hresult GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute bool &success) override; + Core::hresult GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) override; + Core::hresult GetAudioDeviceConnectedStatus(bool &connected, bool &success) override; + Core::hresult GetDeviceList(uint32_t &numberofdevices, IHdmiCecSinkDeviceListIterator*& deviceList, bool &success) override; + Core::hresult GetEnabled(bool &enabled, bool &success) override; + Core::hresult GetOSDName(string &name, bool &success) override; + Core::hresult GetVendorId(string &vendorid, bool &success) override; + Core::hresult PrintDeviceList(bool &printed, bool &success) override; + Core::hresult RequestActiveSource(HdmiCecSinkSuccess &success) override; + Core::hresult RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) override; + Core::hresult SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) override; + Core::hresult SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) override; + Core::hresult SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; + Core::hresult SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; + Core::hresult SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) override; + Core::hresult SendStandbyMessage(HdmiCecSinkSuccess &success) override; + Core::hresult SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) override; + Core::hresult SetActiveSource(HdmiCecSinkSuccess &success) override; + Core::hresult SetEnabled(const bool enabled, HdmiCecSinkSuccess &success) override; + Core::hresult SetOSDName(const string &name, HdmiCecSinkSuccess &success) override; + Core::hresult SetRoutingChange(const string &oldPort, const string &newPort, HdmiCecSinkSuccess &success) override; + Core::hresult SetupARCRouting(const bool enabled, HdmiCecSinkSuccess &success) override; + Core::hresult SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) override; + Core::hresult SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) override; + Core::hresult Configure(PluginHost::IShell* service) override; + Core::hresult Register(Exchange::IHdmiCecSink::INotification *notification) override; + Core::hresult Unregister(Exchange::IHdmiCecSink::INotification *notification) override; private: std::list _hdmiCecSinkNotifications; From 4860f86feddbfa4ea35b8b223c7df0feb12c2ba0 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 09:53:30 -0400 Subject: [PATCH 21/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 5fcc2c9d..2b6fe484 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -483,7 +483,7 @@ namespace WPEFramework { // As the registration/unregistration of notifications is realized by the class PluginHost::JSONRPC, // this class exposes a public method called, Notify(), using this methods, all subscribed clients // will receive a JSONRPC message as a notification, in case this method is called. - class HdmiCecSinkImplementation : public PluginHost::IPlugin, public PluginHost::JSONRPC { + class HdmiCecSinkImplementation : public Exchange::IHdmiCecSource { enum { POLL_THREAD_STATE_NONE, @@ -718,7 +718,7 @@ namespace WPEFramework { public: - Core::hresult GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute bool &success) override; + Core::hresult GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute, bool &success) override; Core::hresult GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) override; Core::hresult GetAudioDeviceConnectedStatus(bool &connected, bool &success) override; Core::hresult GetDeviceList(uint32_t &numberofdevices, IHdmiCecSinkDeviceListIterator*& deviceList, bool &success) override; From 88f60bf3d6d44648a09704d8b8c2dc006777fe68 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 10:39:23 -0400 Subject: [PATCH 22/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 2b6fe484..2ed12f01 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -483,7 +483,7 @@ namespace WPEFramework { // As the registration/unregistration of notifications is realized by the class PluginHost::JSONRPC, // this class exposes a public method called, Notify(), using this methods, all subscribed clients // will receive a JSONRPC message as a notification, in case this method is called. - class HdmiCecSinkImplementation : public Exchange::IHdmiCecSource { + class HdmiCecSinkImplementation : public Exchange::IHdmiCecSink { enum { POLL_THREAD_STATE_NONE, From b9a1c9bca5d676145cf24238e30496b34316be43 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 10:54:33 -0400 Subject: [PATCH 23/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 10 +++++++--- HdmiCecSink/HdmiCecSinkImplementation.h | 16 +++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index cfc2e9b0..c7ee2daa 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -95,6 +95,11 @@ static AllDeviceTypes allDevicetype = ALL_DEVICE_TYPES; static std::vector rcProfile = {RC_PROFILE_TV}; static std::vector deviceFeatures = {DEVICE_FEATURES_TV}; +enum { + DEVICE_POWER_STATE_ON = 0, + DEVICE_POWER_STATE_OFF = 1 +}; + #define API_VERSION_NUMBER_MAJOR 1 #define API_VERSION_NUMBER_MINOR 3 #define API_VERSION_NUMBER_PATCH 7 @@ -591,8 +596,7 @@ namespace WPEFramework //=========================================== HdmiCecSinkImplementation ========================================= HdmiCecSinkImplementation::HdmiCecSinkImplementation() - : PluginHost::JSONRPC() - , _pwrMgrNotification(*this) + : _pwrMgrNotification(*this) , _registeredEventHandlers(false) { LOGWARN("Initlaizing HdmiCecSinkImplementation"); @@ -783,7 +787,7 @@ namespace WPEFramework return Core::ERROR_NONE; } - uint32_t HdmiCecSourceImplementation::Unregister(Exchange::IHdmiCecSink::INotification* notification) + uint32_t HdmiCecSinkImplementation::Unregister(Exchange::IHdmiCecSink::INotification* notification) { LOGINFO("Unregister"); if(notification != nullptr){ diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 2ed12f01..7d3086da 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -528,9 +528,6 @@ namespace WPEFramework { public: HdmiCecSinkImplementation(); virtual ~HdmiCecSinkImplementation(); - virtual const string Initialize(PluginHost::IShell* shell) override; - virtual void Deinitialize(PluginHost::IShell* service) override; - virtual string Information() const override { return {}; } static HdmiCecSinkImplementation* _instance; CECDeviceParams deviceList[16]; std::vector hdmiInputs; @@ -591,16 +588,16 @@ namespace WPEFramework { private: PowerManagerNotification(const PowerManagerNotification&) = delete; PowerManagerNotification& operator=(const PowerManagerNotification&) = delete; - + public: explicit PowerManagerNotification(HdmiCecSinkImplementation& parent) : _parent(parent) { } ~PowerManagerNotification() override = default; - + public: - void OnPowerModeChanged(const PowerState ¤tState, const PowerState &newState) override + void OnPowerModeChanged(const PowerState currentState, const PowerState newState) override { _parent.onPowerModeChanged(currentState, newState); } @@ -611,13 +608,14 @@ namespace WPEFramework { static_assert(std::is_base_of(), "base type mismatch"); return static_cast(this); } - + BEGIN_INTERFACE_MAP(PowerManagerNotification) INTERFACE_ENTRY(Exchange::IPowerManager::IModeChangedNotification) END_INTERFACE_MAP private: HdmiCecSinkImplementation& _parent; + }; // We do not allow this plugin to be copied !! HdmiCecSinkImplementation(const HdmiCecSinkImplementation&) = delete; @@ -736,10 +734,10 @@ namespace WPEFramework { Core::hresult SendStandbyMessage(HdmiCecSinkSuccess &success) override; Core::hresult SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) override; Core::hresult SetActiveSource(HdmiCecSinkSuccess &success) override; - Core::hresult SetEnabled(const bool enabled, HdmiCecSinkSuccess &success) override; + Core::hresult SetEnabled(const bool &enabled, HdmiCecSinkSuccess &success) override; Core::hresult SetOSDName(const string &name, HdmiCecSinkSuccess &success) override; Core::hresult SetRoutingChange(const string &oldPort, const string &newPort, HdmiCecSinkSuccess &success) override; - Core::hresult SetupARCRouting(const bool enabled, HdmiCecSinkSuccess &success) override; + Core::hresult SetupARCRouting(const bool &enabled, HdmiCecSinkSuccess &success) override; Core::hresult SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) override; Core::hresult SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) override; Core::hresult Configure(PluginHost::IShell* service) override; From f600bd615357e687ac25110d426d03e19e1c91c8 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 11:09:27 -0400 Subject: [PATCH 24/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 121 +++++++++++----------- HdmiCecSink/HdmiCecSinkImplementation.h | 1 + 2 files changed, 62 insertions(+), 60 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index c7ee2daa..06ad8d4f 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -78,6 +78,11 @@ #define CEC_SETTING_OSD_NAME "cecOSDName" #define CEC_SETTING_VENDOR_ID "cecVendorId" +enum { + DEVICE_POWER_STATE_ON = 0, + DEVICE_POWER_STATE_OFF = 1 +}; + static std::vector defaultVendorId = {0x00,0x19,0xFB}; static VendorID appVendorId = {defaultVendorId.at(0),defaultVendorId.at(1),defaultVendorId.at(2)}; static VendorID lgVendorId = {0x00,0xE0,0x91}; @@ -95,11 +100,6 @@ static AllDeviceTypes allDevicetype = ALL_DEVICE_TYPES; static std::vector rcProfile = {RC_PROFILE_TV}; static std::vector deviceFeatures = {DEVICE_FEATURES_TV}; -enum { - DEVICE_POWER_STATE_ON = 0, - DEVICE_POWER_STATE_OFF = 1 -}; - #define API_VERSION_NUMBER_MAJOR 1 #define API_VERSION_NUMBER_MINOR 3 #define API_VERSION_NUMBER_PATCH 7 @@ -662,7 +662,8 @@ namespace WPEFramework HdmiCecSinkImplementation::_instance = nullptr; DeinitializeIARM(); } - const std::string HdmiCecSinkImplementation::Configure(PluginHost::IShell *service) + + Core::hresult HdmiCecSinkImplementation::Configure(PluginHost::IShell *service) { InitializePowerManager(service); profileType = searchRdkProfile(); @@ -767,7 +768,7 @@ namespace WPEFramework } - uint32_t HdmiCecSinkImplementation::Register(Exchange::IHdmiCecSink::INotification* notification) + Core::hresult HdmiCecSinkImplementation::Register(Exchange::IHdmiCecSink::INotification* notification) { LOGINFO("Register"); if(notification != nullptr){ @@ -787,7 +788,7 @@ namespace WPEFramework return Core::ERROR_NONE; } - uint32_t HdmiCecSinkImplementation::Unregister(Exchange::IHdmiCecSink::INotification* notification) + Core::hresult HdmiCecSinkImplementation::Unregister(Exchange::IHdmiCecSink::INotification* notification) { LOGINFO("Unregister"); if(notification != nullptr){ @@ -964,7 +965,7 @@ namespace WPEFramework LOGINFO("arcStartStopTimerFunction ARC start timer expired"); LOGINFO("notify_device setting that Initiate ARC failed to get the ARC_STATE_ARC_INITIATED state\n"); params["status"] = string("failure"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ArcInitiationEvent("failure"); index++; } @@ -973,7 +974,7 @@ namespace WPEFramework { LOGINFO("arcStartStopTimerFunction ARC stop timer expired"); LOGINFO("notify_device setting that Terminate ARC failed to get the ARC_STATE_ARC_TERMINATED state\n"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ArcTerminationEvent("failure"); index++; } @@ -992,7 +993,7 @@ namespace WPEFramework LOGERR("Failed to stringify JsonArray"); } - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ShortAudioDescriptorEvent(shortAudioDescriptors); index++; } @@ -1072,7 +1073,7 @@ namespace WPEFramework LOGINFO("panel power state is %s", powerState ? "Off" : "On"); if (powerState == DEVICE_POWER_STATE_ON ) { LOGINFO("Notifying system audio mode ON event"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->SetSystemAudioModeEvent(msg.status.toString()); index++; } @@ -1081,7 +1082,7 @@ namespace WPEFramework } } else { LOGINFO("Notifying system audio Mode OFF event"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->SetSystemAudioModeEvent(msg.status.toString()); index++; } @@ -1104,7 +1105,7 @@ namespace WPEFramework LOGINFO("AudioStatus received from the Audio Device. Updating the AudioStatus info! m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); } LOGINFO("Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n",GetOpName(msg.opCode()),msg.status.getAudioMuteStatus(),msg.status.toString().c_str(),msg.status.getAudioVolume()); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioStatusEvent(msg.status.getAudioMuteStatus(), msg.status.getAudioVolume()); index++; } @@ -1271,7 +1272,7 @@ namespace WPEFramework void HdmiCecSinkImplementation::sendDeviceUpdateInfo(const int logicalAddress) { LOGINFO("Send Device Update Info \n"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnDeviceInfoUpdated(logicalAddress); index++; } @@ -1310,7 +1311,7 @@ namespace WPEFramework if (powerStatus != AUDIO_DEVICE_POWERSTATE_OFF) { if (powerState == DEVICE_POWER_STATE_ON ) { LOGINFO("Notify DS!!! logicalAddress = %d , Audio device power status = %d \n", logicalAddress, powerStatus); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDevicePowerStatus(powerStatus); index++; } @@ -1319,7 +1320,7 @@ namespace WPEFramework } } else { LOGINFO("Notify DS!!! logicalAddress = %d , Audio device power status = %d \n", logicalAddress, powerStatus); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDevicePowerStatus(powerStatus); index++; } @@ -1331,13 +1332,13 @@ namespace WPEFramework if(!HdmiCecSinkImplementation::_instance) return; - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->StandbyMessageReceived(logicalAddress); index++; } } - uint32_t HdmiCecSinkImplementation::SetEnabled(const bool enabled, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetEnabled(const bool enabled, HdmiCecSinkSuccess &success) { LOGINFOMETHOD(); getBoolParameter("enabled", enabled); @@ -1346,25 +1347,25 @@ namespace WPEFramework success.success = true; } - uint32_t HdmiCecSinkImplementation::GetEnabled(bool &enabled, bool &success) + Core::hresult HdmiCecSinkImplementation::GetEnabled(bool &enabled, bool &success) { enabled = getEnabled(); success = true; } - uint32_t HdmiCecSinkImplementation::GetAudioDeviceConnectedStatus(bool &connected, bool &success) + Core::hresult HdmiCecSinkImplementation::GetAudioDeviceConnectedStatus(bool &connected, bool &success) { connected = getAudioDeviceConnectedStatus(); success = true; } - uint32_t HdmiCecSinkImplementation::requestAudioDevicePowerStatusWrapper(const JsonObject& parameters, JsonObject& response) + Core::hresult HdmiCecSinkImplementation::requestAudioDevicePowerStatusWrapper(const JsonObject& parameters, JsonObject& response) { requestAudioDevicePowerStatus(); returnResponse(true); } - uint32_t HdmiCecSinkImplementation::GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) + Core::hresult HdmiCecSinkImplementation::GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) { char routeString[1024] = {'\0'}; int length = 0; @@ -1405,7 +1406,7 @@ namespace WPEFramework } - uint32_t HdmiCecSinkImplementation::GetDeviceList(uint32_t &numberofdevices, IHdmiCecSinkDeviceListIterator*& deviceList, bool &success) + Core::hresult HdmiCecSinkImplementation::GetDeviceList(uint32_t &numberofdevices, IHdmiCecSinkDeviceListIterator*& deviceList, bool &success) { LOGINFOMETHOD(); @@ -1450,7 +1451,7 @@ namespace WPEFramework } - uint32_t HdmiCecSinkImplementation::SetOSDName(const string &name, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetOSDName(const string &name, HdmiCecSinkSuccess &success) { LOGINFOMETHOD(); @@ -1461,27 +1462,27 @@ namespace WPEFramework success.success = true; } - uint32_t HdmiCecSinkImplementation::GetOSDName(string &name, bool &success) + Core::hresult HdmiCecSinkImplementation::GetOSDName(string &name, bool &success) { name = osdName.toString(); LOGINFO("GetOSDName osdName : %s \n",osdName.toString().c_str()); success = true; } - uint32_t HdmiCecSinkImplementation::PrintDeviceList(bool &printed, bool &success) + Core::hresult HdmiCecSinkImplementation::PrintDeviceList(bool &printed, bool &success) { printDeviceList(); printed = true; success = true; } - uint32_t HdmiCecSinkImplementation::SetActiveSource(HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetActiveSource(HdmiCecSinkSuccess &success) { setActiveSource(false); success.success = true; } - uint32_t HdmiCecSinkImplementation::SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) { std::string id = activePath.String(); @@ -1491,7 +1492,7 @@ namespace WPEFramework success.success = true; } - uint32_t HdmiCecSinkImplementation::GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute, bool &success) + Core::hresult HdmiCecSinkImplementation::GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute, bool &success) { std::vector route; char routeString[1024] = {'\0'}; @@ -1559,13 +1560,13 @@ namespace WPEFramework success = true; } - uint32_t HdmiCecSinkImplementation::RequestActiveSource(HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::RequestActiveSource(HdmiCecSinkSuccess &success) { requestActiveSource(); success.success = true; } - uint32_t HdmiCecSinkImplementation::SetRoutingChange(const string &oldPort, const string &newPort, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetRoutingChange(const string &oldPort, const string &newPort, HdmiCecSinkSuccess &success) { if ((oldPort.find("HDMI",0) != std::string::npos || oldPort.find("TV",0) != std::string::npos ) && @@ -1582,7 +1583,7 @@ namespace WPEFramework } - uint32_t HdmiCecSinkImplementation::setMenuLanguageWrapper(const JsonObject& parameters, JsonObject& response) + Core::hresult HdmiCecSinkImplementation::setMenuLanguageWrapper(const JsonObject& parameters, JsonObject& response) { std::string lang; @@ -1596,7 +1597,7 @@ namespace WPEFramework } - uint32_t HdmiCecSinkImplementation::SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) { LOGINFOMETHOD(); @@ -1616,7 +1617,7 @@ namespace WPEFramework success.success = true; } - uint32_t HdmiCecSinkImplementation::SetupARCRouting(const bool enabled, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetupARCRouting(const bool enabled, HdmiCecSinkSuccess &success) { if(enabled) { @@ -1629,31 +1630,31 @@ namespace WPEFramework success.success = true; } - uint32_t HdmiCecSinkImplementation::GetVendorId(string &vendorid, bool &success) + Core::hresult HdmiCecSinkImplementation::GetVendorId(string &vendorid, bool &success) { LOGINFO("GetVendorId appVendorId : %s \n",appVendorId.toString().c_str()); vendorid = appVendorId.toString() ; success = true; } - uint32_t HdmiCecSinkImplementation::RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) { requestShortaudioDescriptor(); success.success = true; } - uint32_t HdmiCecSinkImplementation::SendStandbyMessage(HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendStandbyMessage(HdmiCecSinkSuccess &success) { sendStandbyMessage(); success.success = true; } - uint32_t HdmiCecSinkImplementation::SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) { LOGINFO("%s invoked. \n",__FUNCTION__); systemAudioModeRequest(); success.success = true; } - uint32_t HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) { string logicalAddress = logicalAddress.String(); string keyCode = keyCode.String(); @@ -1669,7 +1670,7 @@ namespace WPEFramework success.success = true; } - uint32_t HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) { string logicalAddress = logicalAddress.String(); string keyCode = keyCode.String(); @@ -1685,7 +1686,7 @@ namespace WPEFramework success.success = true; } - uint32_t HdmiCecSinkImplementation::SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) { string logicalAddress = logicalAddress.String(); SendKeyInfo keyInfo; @@ -1700,12 +1701,12 @@ namespace WPEFramework success.success = true; } - uint32_t HdmiCecSinkImplementation::SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) { sendGiveAudioStatusMsg(); success.success = true; } - uint32_t HdmiCecSinkImplementation::SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) { int video_latency,audio_output_compensated,audio_output_delay; bool low_latency_mode; @@ -1854,13 +1855,13 @@ namespace WPEFramework _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) { /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnWakeupFromStandby(logicalAddress); index++; } } - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnInActiveSource(logicalAddress); index++; } @@ -1882,13 +1883,13 @@ namespace WPEFramework _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) { /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnWakeupFromStandby(logicalAddress); index++; } } - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnTextViewOnMsg(logicalAddress); index++; } @@ -2071,7 +2072,7 @@ namespace WPEFramework _instance->m_currentActiveSource = -1; } - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnInActiveSource(logicalAddress, source.physicalAddress.toString()); index++; } @@ -2104,14 +2105,14 @@ namespace WPEFramework _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) { /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnWakeupFromStandby(logicalAddress); index++; } } string physicalAddress = _instance->deviceList[logical_address].m_physicalAddr.toString().c_str(); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnActiveSourceChange(logicalAddress, physicalAddress); index++; } @@ -2179,7 +2180,7 @@ namespace WPEFramework void HdmiCecSinkImplementation::reportFeatureAbortEvent(const LogicalAddress logicalAddress, const OpCode featureOpcode, const AbortReason abortReason) { LOGINFO(" Notifying the UI FeatureAbort from the %s for the opcode %s with the reason %s ",logicalAddress.toString().c_str(),featureOpcode.toString().c_str(),abortReason.toString().c_str()); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportFeatureAbortEvent(logicalAddress.toInt(), featureOpcode.opCode(), abortReason.toInt()); index++; } @@ -2363,13 +2364,13 @@ namespace WPEFramework { LOGINFO(" logicalAddress =%d , Audio device detected, Notify Device Settings", logicalAddress ); hdmiCecAudioDeviceConnected = true; - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDeviceConnectedStatus("success", "true"); index++; } } - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnDeviceAdded(logicalAddress); index++; } @@ -2411,7 +2412,7 @@ namespace WPEFramework m_audioStatusReceived = false; m_audioStatusTimerStarted = false; LOGINFO("Audio device removed, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDeviceConnectedStatus("success", "false"); index++; } @@ -2419,7 +2420,7 @@ namespace WPEFramework _instance->deviceList[logicalAddress].m_isRequestRetry = 0; _instance->deviceList[logicalAddress].clear(); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnDeviceRemoved(logicalAddress); index++; } @@ -2972,7 +2973,7 @@ namespace WPEFramework cecEnableStatus = true; params["cecEnable"] = string("true"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportCecEnabledEvent("true"); index++; } @@ -3073,7 +3074,7 @@ namespace WPEFramework LOGWARN("CEC Disabled %d",libcecInitStatus); params["cecEnable"] = string("false"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportCecEnabledEvent("false"); index++; } @@ -3221,7 +3222,7 @@ namespace WPEFramework _instance->m_semSignaltoArcRoutingThread.release(); LOGINFO("Got : ARC_INITIATED and notify Device setting"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ArcInitiationEvent("success"); index++; } @@ -3245,7 +3246,7 @@ namespace WPEFramework // trigger callback to Device setting informing to TERMINATE_ARC LOGINFO("Got : ARC_TERMINATED and notify Device setting"); - while (index != _hdmiCecSourceNotifications.end()) { + while (index != _hdmiCecSinkNotifications.end()) { (*index)->ArcTerminationEvent("success"); index++; } diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 7d3086da..7301aadd 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -746,6 +746,7 @@ namespace WPEFramework { private: std::list _hdmiCecSinkNotifications; + mutable Core::CriticalSection _adminLock; }; } // namespace Plugin } // namespace WPEFramework From 144940fee490be784b9e7f7115bc6267dbb149f3 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 11:21:43 -0400 Subject: [PATCH 25/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 33 ++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 06ad8d4f..884da08e 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -794,6 +794,7 @@ namespace WPEFramework if(notification != nullptr){ _adminLock.Lock(); std::list::iterator index = std::find(_hdmiCecSinkNotifications.begin(), _hdmiCecSinkNotifications.end(), notification); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); if(index != _hdmiCecSinkNotifications.end()) { (*index)->Release(); @@ -965,6 +966,7 @@ namespace WPEFramework LOGINFO("arcStartStopTimerFunction ARC start timer expired"); LOGINFO("notify_device setting that Initiate ARC failed to get the ARC_STATE_ARC_INITIATED state\n"); params["status"] = string("failure"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ArcInitiationEvent("failure"); index++; @@ -974,6 +976,7 @@ namespace WPEFramework { LOGINFO("arcStartStopTimerFunction ARC stop timer expired"); LOGINFO("notify_device setting that Terminate ARC failed to get the ARC_STATE_ARC_TERMINATED state\n"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ArcTerminationEvent("failure"); index++; @@ -992,7 +995,7 @@ namespace WPEFramework if (!audiodescriptor.ToString(shortAudioDescriptors)) { LOGERR("Failed to stringify JsonArray"); } - + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ShortAudioDescriptorEvent(shortAudioDescriptors); index++; @@ -1073,6 +1076,7 @@ namespace WPEFramework LOGINFO("panel power state is %s", powerState ? "Off" : "On"); if (powerState == DEVICE_POWER_STATE_ON ) { LOGINFO("Notifying system audio mode ON event"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->SetSystemAudioModeEvent(msg.status.toString()); index++; @@ -1082,6 +1086,7 @@ namespace WPEFramework } } else { LOGINFO("Notifying system audio Mode OFF event"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->SetSystemAudioModeEvent(msg.status.toString()); index++; @@ -1105,6 +1110,7 @@ namespace WPEFramework LOGINFO("AudioStatus received from the Audio Device. Updating the AudioStatus info! m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); } LOGINFO("Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n",GetOpName(msg.opCode()),msg.status.getAudioMuteStatus(),msg.status.toString().c_str(),msg.status.getAudioVolume()); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioStatusEvent(msg.status.getAudioMuteStatus(), msg.status.getAudioVolume()); index++; @@ -1272,6 +1278,7 @@ namespace WPEFramework void HdmiCecSinkImplementation::sendDeviceUpdateInfo(const int logicalAddress) { LOGINFO("Send Device Update Info \n"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnDeviceInfoUpdated(logicalAddress); index++; @@ -1311,6 +1318,7 @@ namespace WPEFramework if (powerStatus != AUDIO_DEVICE_POWERSTATE_OFF) { if (powerState == DEVICE_POWER_STATE_ON ) { LOGINFO("Notify DS!!! logicalAddress = %d , Audio device power status = %d \n", logicalAddress, powerStatus); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDevicePowerStatus(powerStatus); index++; @@ -1320,6 +1328,7 @@ namespace WPEFramework } } else { LOGINFO("Notify DS!!! logicalAddress = %d , Audio device power status = %d \n", logicalAddress, powerStatus); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDevicePowerStatus(powerStatus); index++; @@ -1331,7 +1340,7 @@ namespace WPEFramework { if(!HdmiCecSinkImplementation::_instance) return; - + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->StandbyMessageReceived(logicalAddress); index++; @@ -1855,12 +1864,13 @@ namespace WPEFramework _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) { /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnWakeupFromStandby(logicalAddress); index++; } } - + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnInActiveSource(logicalAddress); index++; @@ -1883,12 +1893,13 @@ namespace WPEFramework _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) { /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnWakeupFromStandby(logicalAddress); index++; } } - + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnTextViewOnMsg(logicalAddress); index++; @@ -2071,7 +2082,7 @@ namespace WPEFramework { _instance->m_currentActiveSource = -1; } - + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnInActiveSource(logicalAddress, source.physicalAddress.toString()); index++; @@ -2105,6 +2116,7 @@ namespace WPEFramework _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus.toInt() == PowerStatus::STANDBY) { /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnWakeupFromStandby(logicalAddress); index++; @@ -2112,6 +2124,7 @@ namespace WPEFramework } string physicalAddress = _instance->deviceList[logical_address].m_physicalAddr.toString().c_str(); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnActiveSourceChange(logicalAddress, physicalAddress); index++; @@ -2180,6 +2193,7 @@ namespace WPEFramework void HdmiCecSinkImplementation::reportFeatureAbortEvent(const LogicalAddress logicalAddress, const OpCode featureOpcode, const AbortReason abortReason) { LOGINFO(" Notifying the UI FeatureAbort from the %s for the opcode %s with the reason %s ",logicalAddress.toString().c_str(),featureOpcode.toString().c_str(),abortReason.toString().c_str()); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportFeatureAbortEvent(logicalAddress.toInt(), featureOpcode.opCode(), abortReason.toInt()); index++; @@ -2364,12 +2378,13 @@ namespace WPEFramework { LOGINFO(" logicalAddress =%d , Audio device detected, Notify Device Settings", logicalAddress ); hdmiCecAudioDeviceConnected = true; + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDeviceConnectedStatus("success", "true"); index++; } } - + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnDeviceAdded(logicalAddress); index++; @@ -2412,6 +2427,7 @@ namespace WPEFramework m_audioStatusReceived = false; m_audioStatusTimerStarted = false; LOGINFO("Audio device removed, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDeviceConnectedStatus("success", "false"); index++; @@ -2420,6 +2436,7 @@ namespace WPEFramework _instance->deviceList[logicalAddress].m_isRequestRetry = 0; _instance->deviceList[logicalAddress].clear(); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->OnDeviceRemoved(logicalAddress); index++; @@ -2973,6 +2990,7 @@ namespace WPEFramework cecEnableStatus = true; params["cecEnable"] = string("true"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportCecEnabledEvent("true"); index++; @@ -3074,6 +3092,7 @@ namespace WPEFramework LOGWARN("CEC Disabled %d",libcecInitStatus); params["cecEnable"] = string("false"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportCecEnabledEvent("false"); index++; @@ -3222,6 +3241,7 @@ namespace WPEFramework _instance->m_semSignaltoArcRoutingThread.release(); LOGINFO("Got : ARC_INITIATED and notify Device setting"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ArcInitiationEvent("success"); index++; @@ -3246,6 +3266,7 @@ namespace WPEFramework // trigger callback to Device setting informing to TERMINATE_ARC LOGINFO("Got : ARC_TERMINATED and notify Device setting"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ArcTerminationEvent("success"); index++; From 12a5bc4a09996f81d669fd08016a8fea7909ae1f Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:05:51 -0400 Subject: [PATCH 26/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 10 +++++----- HdmiCecSink/HdmiCecSinkImplementation.h | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 884da08e..1ef2e932 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -997,7 +997,7 @@ namespace WPEFramework } std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { - (*index)->ShortAudioDescriptorEvent(shortAudioDescriptors); + (*index)->ShortAudiodescriptorEvent(shortAudioDescriptors); index++; } } @@ -1347,7 +1347,7 @@ namespace WPEFramework } } - Core::hresult HdmiCecSinkImplementation::SetEnabled(const bool enabled, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetEnabled(const bool &enabled, HdmiCecSinkSuccess &success) { LOGINFOMETHOD(); getBoolParameter("enabled", enabled); @@ -1421,8 +1421,8 @@ namespace WPEFramework numberofdevices = HdmiCecSinkImplementation::_instance->m_numberOfDevices; LOGINFO("getDeviceListWrapper m_numberOfDevices :%d \n", HdmiCecSinkImplementation::_instance->m_numberOfDevices); - std::vector localDevices; - Exchange::IHdmiCecSource::HdmiCecSinkDevices actual_hdmicecdevices = {0}; + std::vector localDevices; + Exchange::IHdmiCecSink::HdmiCecSinkDevices actual_hdmicecdevices = {0}; for (int n = 0; n <= LogicalAddress::UNREGISTERED; n++) { @@ -1626,7 +1626,7 @@ namespace WPEFramework success.success = true; } - Core::hresult HdmiCecSinkImplementation::SetupARCRouting(const bool enabled, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetupARCRouting(const bool &enabled, HdmiCecSinkSuccess &success) { if(enabled) { diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 7301aadd..49522b44 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -579,8 +579,7 @@ namespace WPEFramework { bool m_audioDevicePowerStatusRequested; BEGIN_INTERFACE_MAP(HdmiCecSinkImplementation) - INTERFACE_ENTRY(PluginHost::IPlugin) - INTERFACE_ENTRY(PluginHost::IDispatcher) + INTERFACE_ENTRY(Exchange::IHdmiCecSink) END_INTERFACE_MAP private: From 51bd4e2f25b97ba4a761df47db9b179706062d09 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:14:21 -0400 Subject: [PATCH 27/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 1ef2e932..4b475af7 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -794,7 +794,6 @@ namespace WPEFramework if(notification != nullptr){ _adminLock.Lock(); std::list::iterator index = std::find(_hdmiCecSinkNotifications.begin(), _hdmiCecSinkNotifications.end(), notification); - std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); if(index != _hdmiCecSinkNotifications.end()) { (*index)->Release(); @@ -1349,8 +1348,6 @@ namespace WPEFramework } Core::hresult HdmiCecSinkImplementation::SetEnabled(const bool &enabled, HdmiCecSinkSuccess &success) { - LOGINFOMETHOD(); - getBoolParameter("enabled", enabled); setEnabled(enabled); success.success = true; @@ -1417,7 +1414,6 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::GetDeviceList(uint32_t &numberofdevices, IHdmiCecSinkDeviceListIterator*& deviceList, bool &success) { - LOGINFOMETHOD(); numberofdevices = HdmiCecSinkImplementation::_instance->m_numberOfDevices; LOGINFO("getDeviceListWrapper m_numberOfDevices :%d \n", HdmiCecSinkImplementation::_instance->m_numberOfDevices); @@ -1462,7 +1458,6 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::SetOSDName(const string &name, HdmiCecSinkSuccess &success) { - LOGINFOMETHOD(); LOGINFO("SetOSDName osdName: %s",name.c_str()); osdName = name.c_str(); @@ -1608,7 +1603,6 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) { - LOGINFOMETHOD(); unsigned int vendorID = 0x00; try From 0a22550c016db5f06d91ca5a79c296906d043106 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:26:45 -0400 Subject: [PATCH 28/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 190 +++++++++++++++------- 1 file changed, 130 insertions(+), 60 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 4b475af7..65fb7486 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -665,15 +665,9 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::Configure(PluginHost::IShell *service) { - InitializePowerManager(service); + InitializePowerManager(service); profileType = searchRdkProfile(); - if (profileType == STB || profileType == NOT_FOUND) - { - LOGINFO("Invalid profile type for TV \n"); - return (std::string("Not supported")); - } - HdmiCecSinkImplementation::_instance = this; smConnection=NULL; cecEnableStatus = false; @@ -764,7 +758,7 @@ namespace WPEFramework } getCecVersion(); LOGINFO(" HdmiCecSinkImplementation plugin Initialize completed \n"); - return (std::string()); + return Core::ERROR_NONE; } @@ -850,7 +844,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if (IARM_BUS_DSMGR_EVENT_HDMI_IN_HOTPLUG == eventId) { @@ -865,7 +861,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::onPowerModeChanged(const PowerState ¤tState, const PowerState &newState) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } LOGINFO("Event IARM_BUS_PWRMGR_EVENT_MODECHANGED: State Changed %d -- > %d\r", currentState, newState); @@ -910,7 +908,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::sendStandbyMessage() { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(HdmiCecSinkImplementation::_instance->smConnection)) return; if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ @@ -1095,19 +1095,21 @@ namespace WPEFramework void HdmiCecSinkImplementation::Process_ReportAudioStatus_msg(const ReportAudioStatus msg) { if(!HdmiCecSinkImplementation::_instance) + { return; - if (m_audioStatusTimerStarted) - { - m_audioStatusReceived = true; - m_isAudioStatusInfoUpdated = true; - m_audioStatusTimerStarted = false; - if (m_audioStatusDetectionTimer.isActive()) - { - LOGINFO("AudioStatus received from the Audio Device and the timer is still active. So stopping the timer!\n"); - m_audioStatusDetectionTimer.stop(); - } - LOGINFO("AudioStatus received from the Audio Device. Updating the AudioStatus info! m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); - } + } + if (m_audioStatusTimerStarted) + { + m_audioStatusReceived = true; + m_isAudioStatusInfoUpdated = true; + m_audioStatusTimerStarted = false; + if (m_audioStatusDetectionTimer.isActive()) + { + LOGINFO("AudioStatus received from the Audio Device and the timer is still active. So stopping the timer!\n"); + m_audioStatusDetectionTimer.stop(); + } + LOGINFO("AudioStatus received from the Audio Device. Updating the AudioStatus info! m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); + } LOGINFO("Command: ReportAudioStatus %s audio Mute status %d means %s and current Volume level is %d \n",GetOpName(msg.opCode()),msg.status.getAudioMuteStatus(),msg.status.toString().c_str(),msg.status.getAudioVolume()); std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { @@ -1292,21 +1294,29 @@ namespace WPEFramework } if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(_instance->smConnection)) + { return; - LOGINFO(" Send systemAudioModeRequest "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(SystemAudioModeRequest(physical_addr)), 1000); + } + LOGINFO(" Send systemAudioModeRequest "); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(SystemAudioModeRequest(physical_addr)), 1000); } void HdmiCecSinkImplementation::sendGiveAudioStatusMsg() { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(_instance->smConnection)) + { return; - LOGINFO(" Send GiveAudioStatus "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(GiveAudioStatus()), 100); + } + LOGINFO(" Send GiveAudioStatus "); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(GiveAudioStatus()), 100); } void HdmiCecSinkImplementation::reportAudioDevicePowerStatusInfo(const int logicalAddress, const int powerStatus) @@ -1338,7 +1348,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::SendStandbyMsgEvent(const int logicalAddress) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->StandbyMessageReceived(logicalAddress); @@ -1846,7 +1858,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::updateImageViewOn(const int logicalAddress) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || logicalAddress == LogicalAddress::UNREGISTERED ){ @@ -1875,7 +1889,9 @@ namespace WPEFramework { JsonObject params; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || logicalAddress == LogicalAddress::UNREGISTERED ){ @@ -1904,7 +1920,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::updateDeviceChain(const LogicalAddress &logicalAddress, const PhysicalAddress &phy_addr) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ LOGERR("Logical Address NOT Allocated"); @@ -1927,7 +1945,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::getActiveRoute(const LogicalAddress &logicalAddress, std::vector &route) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || logicalAddress.toInt() == LogicalAddress::UNREGISTERED ){ @@ -1990,10 +2010,14 @@ namespace WPEFramework void HdmiCecSinkImplementation::requestActiveSource() { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } - if(!(_instance->smConnection)) - return; + if(!(_instance->smConnection)) + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ LOGERR("Logical Address NOT Allocated"); return; @@ -2006,10 +2030,14 @@ namespace WPEFramework void HdmiCecSinkImplementation::setActiveSource(bool isResponse) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(_instance->smConnection)) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ LOGERR("Logical Address NOT Allocated"); return; @@ -2029,7 +2057,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::setCurrentLanguage(const Language &lang) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ LOGERR("Logical Address NOT Allocated"); @@ -2043,10 +2073,14 @@ namespace WPEFramework { Language lang = ""; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(_instance->smConnection)) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ LOGERR("Logical Address NOT Allocated"); return; @@ -2061,7 +2095,9 @@ namespace WPEFramework { JsonObject params; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ LOGERR("Logical Address NOT Allocated"); @@ -2088,7 +2124,9 @@ namespace WPEFramework { JsonObject params; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ LOGERR("Logical Address NOT Allocated"); @@ -2135,10 +2173,14 @@ namespace WPEFramework } if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(_instance->smConnection)) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ LOGERR("Logical Address NOT Allocated"); return; @@ -2161,7 +2203,9 @@ namespace WPEFramework return; if(!(_instance->smConnection)) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED ){ LOGERR("Logical Address NOT Allocated"); return; @@ -2199,7 +2243,9 @@ namespace WPEFramework int i; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(_instance->smConnection)) return; @@ -2264,7 +2310,9 @@ namespace WPEFramework int i; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } for(i=0; i< 16; i++) { @@ -2279,10 +2327,14 @@ namespace WPEFramework void HdmiCecSinkImplementation::setStreamPath( const PhysicalAddress &physical_addr) { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(_instance->smConnection)) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ LOGERR("Logical Address NOT Allocated Or its not valid"); return; @@ -2298,7 +2350,9 @@ namespace WPEFramework int newPortID = -1; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ LOGERR("Logical Address NOT Allocated Or its not valid"); @@ -2346,7 +2400,9 @@ namespace WPEFramework } if(!(_instance->smConnection)) - return; + { + return; + } _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(RoutingChange(oldPhyAddr, newPhyAddr)), 500); } @@ -2354,7 +2410,9 @@ namespace WPEFramework JsonObject params; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ LOGERR("Logical Address NOT Allocated"); @@ -2390,7 +2448,9 @@ namespace WPEFramework JsonObject params; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED){ LOGERR("Logical Address NOT Allocated"); @@ -2442,9 +2502,13 @@ namespace WPEFramework int requestType; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(!(_instance->smConnection)) - return; + { + return; + } if ( _instance->m_logicalAddressAllocated == LogicalAddress::UNREGISTERED || logicalAddress >= LogicalAddress::UNREGISTERED + TEST_ADD ){ LOGERR("Logical Address NOT Allocated Or its not valid"); return; @@ -3175,7 +3239,9 @@ namespace WPEFramework return; } if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } if(m_currentArcRoutingState == ARC_STATE_REQUEST_ARC_TERMINATION || m_currentArcRoutingState == ARC_STATE_ARC_TERMINATED) { LOGINFO("ARC is either Termination in progress or already Terminated"); @@ -3270,7 +3336,9 @@ namespace WPEFramework void HdmiCecSinkImplementation::threadSendKeyEvent() { if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } SendKeyInfo keyInfo = {-1,-1}; @@ -3364,7 +3432,9 @@ namespace WPEFramework uint32_t currentArcRoutingState; if(!HdmiCecSinkImplementation::_instance) - return; + { + return; + } LOGINFO("Running threadArcRouting"); _instance->getHdmiArcPortID(); From d35d201f28dccb87a38996caae09eae9677bd08a Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:40:10 -0400 Subject: [PATCH 29/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 29 +++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 65fb7486..f19e0fc1 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -1363,24 +1363,27 @@ namespace WPEFramework setEnabled(enabled); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::GetEnabled(bool &enabled, bool &success) { enabled = getEnabled(); success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::GetAudioDeviceConnectedStatus(bool &connected, bool &success) { connected = getAudioDeviceConnectedStatus(); success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::requestAudioDevicePowerStatusWrapper(const JsonObject& parameters, JsonObject& response) { requestAudioDevicePowerStatus(); - returnResponse(true); + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) @@ -1421,6 +1424,7 @@ namespace WPEFramework } success = true; + return Core::ERROR_NONE; } @@ -1465,6 +1469,7 @@ namespace WPEFramework deviceList = new HdmiCecSinkDeviceListIterator(localDevices); success = true; + return Core::ERROR_NONE; } @@ -1476,6 +1481,7 @@ namespace WPEFramework Utils::persistJsonSettings (CEC_SETTING_ENABLED_FILE, CEC_SETTING_OSD_NAME, JsonValue(name.c_str())); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::GetOSDName(string &name, bool &success) @@ -1483,6 +1489,7 @@ namespace WPEFramework name = osdName.toString(); LOGINFO("GetOSDName osdName : %s \n",osdName.toString().c_str()); success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::PrintDeviceList(bool &printed, bool &success) @@ -1490,12 +1497,14 @@ namespace WPEFramework printDeviceList(); printed = true; success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SetActiveSource(HdmiCecSinkSuccess &success) { setActiveSource(false); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) @@ -1506,6 +1515,7 @@ namespace WPEFramework LOGINFO("Addr = %s, length = %zu", id.c_str(), id.length()); setStreamPath(phy_addr); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::GetActiveRoute(bool &available, uint8_t &length, IHdmiCecSinkActivePathIterator*& pathList, string &ActiveRoute, bool &success) @@ -1574,12 +1584,14 @@ namespace WPEFramework } success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::RequestActiveSource(HdmiCecSinkSuccess &success) { requestActiveSource(); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SetRoutingChange(const string &oldPort, const string &newPort, HdmiCecSinkSuccess &success) @@ -1596,6 +1608,7 @@ namespace WPEFramework { success.success = false; } + return Core::ERROR_NONE; } @@ -1609,7 +1622,7 @@ namespace WPEFramework setCurrentLanguage(Language(lang.data())); sendMenuLanguage(); - returnResponse(true); + return Core::ERROR_NONE; } @@ -1631,6 +1644,7 @@ namespace WPEFramework Utils::persistJsonSettings (CEC_SETTING_ENABLED_FILE, CEC_SETTING_VENDOR_ID, JsonValue(vendorID)); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SetupARCRouting(const bool &enabled, HdmiCecSinkSuccess &success) { @@ -1644,23 +1658,28 @@ namespace WPEFramework } success.success = true; + return Core::ERROR_NONE; } + Core::hresult HdmiCecSinkImplementation::GetVendorId(string &vendorid, bool &success) { LOGINFO("GetVendorId appVendorId : %s \n",appVendorId.toString().c_str()); vendorid = appVendorId.toString() ; success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) { requestShortaudioDescriptor(); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SendStandbyMessage(HdmiCecSinkSuccess &success) { sendStandbyMessage(); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) @@ -1668,6 +1687,7 @@ namespace WPEFramework LOGINFO("%s invoked. \n",__FUNCTION__); systemAudioModeRequest(); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) { @@ -1683,6 +1703,7 @@ namespace WPEFramework m_sendKeyCV.notify_one(); LOGINFO("Post send key press event to queue size:%zu \n",m_SendKeyQueue.size()); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) @@ -1699,6 +1720,7 @@ namespace WPEFramework m_sendKeyCV.notify_one(); LOGINFO("User control pressed, queue size:%zu \n",m_SendKeyQueue.size()); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) @@ -1714,12 +1736,14 @@ namespace WPEFramework m_sendKeyCV.notify_one(); LOGINFO("User Control Released, queue size:%zu \n",m_SendKeyQueue.size()); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) { sendGiveAudioStatusMsg(); success.success = true; + return Core::ERROR_NONE; } Core::hresult HdmiCecSinkImplementation::SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) { @@ -1734,6 +1758,7 @@ namespace WPEFramework updateCurrentLatency(video_latency, low_latency_mode,audio_output_compensated, audio_output_delay); success.success = true; + return Core::ERROR_NONE; } bool HdmiCecSinkImplementation::loadSettings() { From 8800d69b0c8e37e8a08a7da454d2e2d9c96701db Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 12:53:20 -0400 Subject: [PATCH 30/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 26 ++++++----------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index f19e0fc1..83368874 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -1380,15 +1380,9 @@ namespace WPEFramework return Core::ERROR_NONE; } - Core::hresult HdmiCecSinkImplementation::requestAudioDevicePowerStatusWrapper(const JsonObject& parameters, JsonObject& response) - { - requestAudioDevicePowerStatus(); - return Core::ERROR_NONE; - } - Core::hresult HdmiCecSinkImplementation::GetActiveSource(bool &available, uint8_t &logicalAddress, string &physicalAddress, string &deviceType, string &cecVersion, string &osdName, string &vendorID, string &powerStatus, string &port, bool &success) { - char routeString[1024] = {'\0'}; + char routeString[1024] = {'\0'}; int length = 0; std::stringstream temp; @@ -1467,7 +1461,7 @@ namespace WPEFramework } } - deviceList = new HdmiCecSinkDeviceListIterator(localDevices); + deviceList = (Core::Service>::Create(localDevices)); success = true; return Core::ERROR_NONE; } @@ -1510,9 +1504,8 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) { - std::string id = activePath.String(); - PhysicalAddress phy_addr = PhysicalAddress(id); - LOGINFO("Addr = %s, length = %zu", id.c_str(), id.length()); + PhysicalAddress phy_addr = PhysicalAddress(activePath); + LOGINFO("Addr = %s, length = %zu", activePath.c_str(), activePath.length()); setStreamPath(phy_addr); success.success = true; return Core::ERROR_NONE; @@ -1522,7 +1515,6 @@ namespace WPEFramework { std::vector route; char routeString[1024] = {'\0'}; - int length = 0; std::vector paths; std::stringstream temp; @@ -1563,7 +1555,7 @@ namespace WPEFramework } } - pathList = new HdmiCecSinkActivePathIterator(paths); + pathList = (Core::Service>::Create(paths)); temp << (char *)routeString; ActiveRoute = temp.str(); LOGINFO("ActiveRoute = [%s]", routeString); @@ -1691,8 +1683,6 @@ namespace WPEFramework } Core::hresult HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) { - string logicalAddress = logicalAddress.String(); - string keyCode = keyCode.String(); SendKeyInfo keyInfo; keyInfo.logicalAddr = stoi(logicalAddress); keyInfo.keyCode = stoi(keyCode); @@ -1708,8 +1698,7 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) { - string logicalAddress = logicalAddress.String(); - string keyCode = keyCode.String(); + SendKeyInfo keyInfo; keyInfo.logicalAddr = stoi(logicalAddress); keyInfo.keyCode = stoi(keyCode); @@ -1725,8 +1714,7 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) { - string logicalAddress = logicalAddress.String(); - SendKeyInfo keyInfo; + keyInfo.logicalAddr = stoi(logicalAddress); keyInfo.keyCode = 0; keyInfo.UserControl = "sendUserControlReleased"; From 6e8905d3f0d5c013450bcd35e20ad01edaa3272a Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 13:09:42 -0400 Subject: [PATCH 31/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 31 ++++++----------------- HdmiCecSink/HdmiCecSinkImplementation.h | 6 ++--- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 83368874..d6e11061 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -1426,7 +1426,7 @@ namespace WPEFramework { numberofdevices = HdmiCecSinkImplementation::_instance->m_numberOfDevices; - LOGINFO("getDeviceListWrapper m_numberOfDevices :%d \n", HdmiCecSinkImplementation::_instance->m_numberOfDevices); + LOGINFO("getDeviceList m_numberOfDevices :%d \n", HdmiCecSinkImplementation::_instance->m_numberOfDevices); std::vector localDevices; Exchange::IHdmiCecSink::HdmiCecSinkDevices actual_hdmicecdevices = {0}; @@ -1445,10 +1445,10 @@ namespace WPEFramework actual_hdmicecdevices.vendorID = HdmiCecSinkImplementation::_instance->deviceList[n].m_vendorID.toString().c_str(); actual_hdmicecdevices.powerStatus = HdmiCecSinkImplementation::_instance->deviceList[n].m_powerStatus.toString().c_str(); int hdmiPortNumber = -1; - LOGINFO("getDeviceListWrapper m_numofHdmiInput:%d looking for Logical Address :%d \n", m_numofHdmiInput, HdmiCecSinkImplementation::_instance->deviceList[n].m_logicalAddress.toInt()); + LOGINFO("getDeviceList m_numofHdmiInput:%d looking for Logical Address :%d \n", m_numofHdmiInput, HdmiCecSinkImplementation::_instance->deviceList[n].m_logicalAddress.toInt()); for (int i=0; i < m_numofHdmiInput; i++) { - LOGINFO("getDeviceListWrapper connected : %d, portid:%d LA: %d \n", hdmiInputs[i].m_isConnected, hdmiInputs[i].m_portID, hdmiInputs[i].m_logicalAddr.toInt()); + LOGINFO("getDeviceList connected : %d, portid:%d LA: %d \n", hdmiInputs[i].m_isConnected, hdmiInputs[i].m_portID, hdmiInputs[i].m_logicalAddr.toInt()); if(hdmiInputs[i].m_isConnected && hdmiInputs[i].m_logicalAddr.toInt() == HdmiCecSinkImplementation::_instance->deviceList[n].m_logicalAddress.toInt()) { hdmiPortNumber = hdmiInputs[i].m_portID; @@ -1501,11 +1501,10 @@ namespace WPEFramework return Core::ERROR_NONE; } - Core::hresult HdmiCecSinkImplementation::SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetActivePath(const string activePath, HdmiCecSinkSuccess &success) { - PhysicalAddress phy_addr = PhysicalAddress(activePath); - LOGINFO("Addr = %s, length = %zu", activePath.c_str(), activePath.length()); + LOGINFO("Addr = %s, length = %zu", activePathStr.c_str(), activePathStr.length()); setStreamPath(phy_addr); success.success = true; return Core::ERROR_NONE; @@ -1604,20 +1603,6 @@ namespace WPEFramework } - Core::hresult HdmiCecSinkImplementation::setMenuLanguageWrapper(const JsonObject& parameters, JsonObject& response) - { - std::string lang; - - returnIfParamNotFound(parameters, "language"); - - lang = parameters["language"].String(); - - setCurrentLanguage(Language(lang.data())); - sendMenuLanguage(); - return Core::ERROR_NONE; - } - - Core::hresult HdmiCecSinkImplementation::SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) { @@ -1628,7 +1613,7 @@ namespace WPEFramework } catch (...) { - LOGWARN("Exception in setVendorIdWrapper set default value\n"); + LOGWARN("Exception in setVendorId set default value\n"); vendorID = 0x0019FB; } appVendorId = {(uint8_t)(vendorID >> 16 & 0xff),(uint8_t)(vendorID>> 8 & 0xff),(uint8_t) (vendorID & 0xff)}; @@ -1681,7 +1666,7 @@ namespace WPEFramework success.success = true; return Core::ERROR_NONE; } - Core::hresult HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t logicalAddress, const uint32_t keyCode, HdmiCecSinkSuccess &success) { SendKeyInfo keyInfo; keyInfo.logicalAddr = stoi(logicalAddress); @@ -1696,7 +1681,7 @@ namespace WPEFramework return Core::ERROR_NONE; } - Core::hresult HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t logicalAddress, const uint32_t keyCode, HdmiCecSinkSuccess &success) { SendKeyInfo keyInfo; diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 49522b44..debe397d 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -727,11 +727,11 @@ namespace WPEFramework { Core::hresult RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) override; Core::hresult SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) override; Core::hresult SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) override; - Core::hresult SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; - Core::hresult SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; + Core::hresult SendKeyPressEvent(const uint32_t logicalAddress, const uint32_t keyCode, HdmiCecSinkSuccess &success) override; + Core::hresult SendUserControlPressed(const uint32_t logicalAddress, const uint32_t keyCode, HdmiCecSinkSuccess &success) override; Core::hresult SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) override; Core::hresult SendStandbyMessage(HdmiCecSinkSuccess &success) override; - Core::hresult SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) override; + Core::hresult SetActivePath(const string activePath, HdmiCecSinkSuccess &success) override; Core::hresult SetActiveSource(HdmiCecSinkSuccess &success) override; Core::hresult SetEnabled(const bool &enabled, HdmiCecSinkSuccess &success) override; Core::hresult SetOSDName(const string &name, HdmiCecSinkSuccess &success) override; From 67a1cde5ddc72627436d341624b1d7a888c9beb5 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 13:23:32 -0400 Subject: [PATCH 32/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 20 +++++++++++--------- HdmiCecSink/HdmiCecSinkImplementation.h | 6 +++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index d6e11061..a300afff 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -1501,9 +1501,10 @@ namespace WPEFramework return Core::ERROR_NONE; } - Core::hresult HdmiCecSinkImplementation::SetActivePath(const string activePath, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) { - PhysicalAddress phy_addr = PhysicalAddress(activePath); + string activePathStr = activePath; + PhysicalAddress phy_addr = PhysicalAddress(activePathStr); LOGINFO("Addr = %s, length = %zu", activePathStr.c_str(), activePathStr.length()); setStreamPath(phy_addr); success.success = true; @@ -1666,11 +1667,12 @@ namespace WPEFramework success.success = true; return Core::ERROR_NONE; } - Core::hresult HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t logicalAddress, const uint32_t keyCode, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) { SendKeyInfo keyInfo; - keyInfo.logicalAddr = stoi(logicalAddress); - keyInfo.keyCode = stoi(keyCode); + + keyInfo.logicalAddr = logicalAddress; + keyInfo.keyCode = keyCode; keyInfo.UserControl = "sendKeyPressEvent"; std::unique_lock lk(m_sendKeyEventMutex); m_SendKeyQueue.push(keyInfo); @@ -1681,12 +1683,12 @@ namespace WPEFramework return Core::ERROR_NONE; } - Core::hresult HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t logicalAddress, const uint32_t keyCode, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) { SendKeyInfo keyInfo; - keyInfo.logicalAddr = stoi(logicalAddress); - keyInfo.keyCode = stoi(keyCode); + keyInfo.logicalAddr = logicalAddress; + keyInfo.keyCode = keyCode; keyInfo.UserControl = "sendUserControlPressed"; std::unique_lock lk(m_sendKeyEventMutex); m_SendKeyQueue.push(keyInfo); @@ -1700,7 +1702,7 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) { - keyInfo.logicalAddr = stoi(logicalAddress); + keyInfo.logicalAddr = logicalAddress; keyInfo.keyCode = 0; keyInfo.UserControl = "sendUserControlReleased"; std::unique_lock lk(m_sendKeyEventMutex); diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index debe397d..49522b44 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -727,11 +727,11 @@ namespace WPEFramework { Core::hresult RequestShortAudioDescriptor(HdmiCecSinkSuccess &success) override; Core::hresult SendAudioDevicePowerOnMessage(HdmiCecSinkSuccess &success) override; Core::hresult SendGetAudioStatusMessage(HdmiCecSinkSuccess &success) override; - Core::hresult SendKeyPressEvent(const uint32_t logicalAddress, const uint32_t keyCode, HdmiCecSinkSuccess &success) override; - Core::hresult SendUserControlPressed(const uint32_t logicalAddress, const uint32_t keyCode, HdmiCecSinkSuccess &success) override; + Core::hresult SendKeyPressEvent(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; + Core::hresult SendUserControlPressed(const uint32_t &logicalAddress, const uint32_t &keyCode, HdmiCecSinkSuccess &success) override; Core::hresult SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) override; Core::hresult SendStandbyMessage(HdmiCecSinkSuccess &success) override; - Core::hresult SetActivePath(const string activePath, HdmiCecSinkSuccess &success) override; + Core::hresult SetActivePath(const string &activePath, HdmiCecSinkSuccess &success) override; Core::hresult SetActiveSource(HdmiCecSinkSuccess &success) override; Core::hresult SetEnabled(const bool &enabled, HdmiCecSinkSuccess &success) override; Core::hresult SetOSDName(const string &name, HdmiCecSinkSuccess &success) override; From 1daff7eaddfd2c32254ac28c21b5734a748ca45a Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 13:40:04 -0400 Subject: [PATCH 33/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index a300afff..4ed5f673 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -1701,7 +1701,7 @@ namespace WPEFramework Core::hresult HdmiCecSinkImplementation::SendUserControlReleased(const uint32_t &logicalAddress, HdmiCecSinkSuccess &success) { - + SendKeyInfo keyInfo; keyInfo.logicalAddr = logicalAddress; keyInfo.keyCode = 0; keyInfo.UserControl = "sendUserControlReleased"; @@ -1880,7 +1880,7 @@ namespace WPEFramework } std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { - (*index)->OnInActiveSource(logicalAddress); + (*index)->OnInActiveSource(logicalAddress, _instance->deviceList[logicalAddress].m_physicalAddr.toString()); index++; } } @@ -2022,9 +2022,11 @@ namespace WPEFramework LOGERR("Logical Address NOT Allocated"); return; } + HdmiCecSinkSuccess success; + success.success = true; _instance->smConnection->sendTo(LogicalAddress::BROADCAST, - MessageEncoder().encode(RequestActiveSource()), 500); + MessageEncoder().encode(RequestActiveSource(success)), 500); } void HdmiCecSinkImplementation::setActiveSource(bool isResponse) @@ -2114,7 +2116,7 @@ namespace WPEFramework } std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { - (*index)->OnInActiveSource(logicalAddress, source.physicalAddress.toString()); + (*index)->OnInActiveSource(logical_address, source.physicalAddress.toString()); index++; } } @@ -2150,7 +2152,7 @@ namespace WPEFramework /* Bringing TV out of standby is handled by application.notify UI to bring the TV out of standby */ std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { - (*index)->OnWakeupFromStandby(logicalAddress); + (*index)->OnWakeupFromStandby(logical_address); index++; } } @@ -2158,7 +2160,7 @@ namespace WPEFramework string physicalAddress = _instance->deviceList[logical_address].m_physicalAddr.toString().c_str(); std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { - (*index)->OnActiveSourceChange(logicalAddress, physicalAddress); + (*index)->OnActiveSourceChange(logical_address, physicalAddress); index++; } } From b5e02f4029dc39031cad6e0a8792de8f71e88b42 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 13:56:15 -0400 Subject: [PATCH 34/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 4ed5f673..e66c6f48 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -2022,11 +2022,10 @@ namespace WPEFramework LOGERR("Logical Address NOT Allocated"); return; } - HdmiCecSinkSuccess success; - success.success = true; + _instance->smConnection->sendTo(LogicalAddress::BROADCAST, - MessageEncoder().encode(RequestActiveSource(success)), 500); + MessageEncoder().encode(RequestActiveSource::RequestActiveSource()), 500); } void HdmiCecSinkImplementation::setActiveSource(bool isResponse) @@ -2189,7 +2188,7 @@ namespace WPEFramework } LOGINFO(" Send requestShortAudioDescriptor Message "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestShortAudioDescriptor(formatid,audioFormatCode,numberofdescriptor)), 1000); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestShortAudioDescriptor::RequestShortAudioDescriptor(formatid,audioFormatCode,numberofdescriptor)), 1000); } From 56e8a596bd42892b5bcd6273dc370db884541f87 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 14:37:10 -0400 Subject: [PATCH 35/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index e66c6f48..a8a8f74b 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -2025,7 +2025,7 @@ namespace WPEFramework _instance->smConnection->sendTo(LogicalAddress::BROADCAST, - MessageEncoder().encode(RequestActiveSource::RequestActiveSource()), 500); + MessageEncoder().encode(RequestActiveSource()), 500); } void HdmiCecSinkImplementation::setActiveSource(bool isResponse) @@ -2188,7 +2188,7 @@ namespace WPEFramework } LOGINFO(" Send requestShortAudioDescriptor Message "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestShortAudioDescriptor::RequestShortAudioDescriptor(formatid,audioFormatCode,numberofdescriptor)), 1000); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestShortAudioDescriptor(formatid,audioFormatCode,numberofdescriptor)), 1000); } From 94aa0765b6083d99905a084d99e41b08fa914499 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:18:11 -0400 Subject: [PATCH 36/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 6 +++--- HdmiCecSource/HdmiCecSourceImplementation.cpp | 4 ++-- Tests/L1Tests/tests/test_HdmiCecSource.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index a8a8f74b..d43367ab 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -177,7 +177,7 @@ namespace WPEFramework HdmiCecSinkImplementation::_instance->addDevice(header.from.toInt()); HdmiCecSinkImplementation::_instance->updateTextViewOn(header.from.toInt()); } - void HdmiCecSinkProcessor::process (const RequestActiveSource &msg, const Header &header) + void HdmiCecSinkProcessor::process (const RequestActiveSourceMessage &msg, const Header &header) { printHeader(header); LOGINFO("Command: RequestActiveSource\n"); @@ -2025,7 +2025,7 @@ namespace WPEFramework _instance->smConnection->sendTo(LogicalAddress::BROADCAST, - MessageEncoder().encode(RequestActiveSource()), 500); + MessageEncoder().encode(RequestActiveSourceMessage()), 500); } void HdmiCecSinkImplementation::setActiveSource(bool isResponse) @@ -2188,7 +2188,7 @@ namespace WPEFramework } LOGINFO(" Send requestShortAudioDescriptor Message "); - _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestShortAudioDescriptor(formatid,audioFormatCode,numberofdescriptor)), 1000); + _instance->smConnection->sendTo(LogicalAddress::AUDIO_SYSTEM,MessageEncoder().encode(RequestShortAudioDescriptorMessage(formatid,audioFormatCode,numberofdescriptor)), 1000); } diff --git a/HdmiCecSource/HdmiCecSourceImplementation.cpp b/HdmiCecSource/HdmiCecSourceImplementation.cpp index 4a4e3e64..50809956 100644 --- a/HdmiCecSource/HdmiCecSourceImplementation.cpp +++ b/HdmiCecSource/HdmiCecSourceImplementation.cpp @@ -135,7 +135,7 @@ namespace WPEFramework LOGINFO("Command: TextViewOn\n"); HdmiCecSourceImplementation::_instance->addDevice(header.from.toInt()); } - void HdmiCecSourceProcessor::process (const RequestActiveSource &msg, const Header &header) + void HdmiCecSourceProcessor::process (const RequestActiveSourceMessage &msg, const Header &header) { printHeader(header); LOGINFO("Command: RequestActiveSource\n"); @@ -1031,7 +1031,7 @@ namespace WPEFramework LOGINFO("Command: sending GiveDevicePowerStatus \r\n"); smConnection->sendTo(LogicalAddress::TV, MessageEncoder().encode(GiveDevicePowerStatus())); LOGINFO("Command: sending request active Source isDeviceActiveSource is set to false\r\n"); - smConnection->sendTo(LogicalAddress::BROADCAST, MessageEncoder().encode(RequestActiveSource())); + smConnection->sendTo(LogicalAddress::BROADCAST, MessageEncoder().encode(RequestActiveSourceMessage())); isDeviceActiveSource = false; LOGINFO("Command: GiveDeviceVendorID sending VendorID response :%s\n", \ (isLGTvConnected)?lgVendorId.toString().c_str():appVendorId.toString().c_str()); diff --git a/Tests/L1Tests/tests/test_HdmiCecSource.cpp b/Tests/L1Tests/tests/test_HdmiCecSource.cpp index 9a08cadb..a51ac917 100755 --- a/Tests/L1Tests/tests/test_HdmiCecSource.cpp +++ b/Tests/L1Tests/tests/test_HdmiCecSource.cpp @@ -1000,7 +1000,7 @@ TEST_F(HdmiCecSourceInitializedEventTest, requestActiveSourceProccess){ Header header; header.from = LogicalAddress(1); //specifies with logicalAddress in the deviceList we're using - RequestActiveSource requestActiveSource; + RequestActiveSourceMessage requestActiveSource; Plugin::HdmiCecSourceProcessor proc(Connection::getInstance()); From 95e9a664b72b6c7d1c79060535ac1215a0532eca Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:41:39 -0400 Subject: [PATCH 37/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 49522b44..0babdf7f 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -69,7 +69,7 @@ namespace WPEFramework { void process (const InActiveSource &msg, const Header &header); void process (const ImageViewOn &msg, const Header &header); void process (const TextViewOn &msg, const Header &header); - void process (const RequestActiveSource &msg, const Header &header); + void process (const RequestActiveSourceMessage &msg, const Header &header); void process (const Standby &msg, const Header &header); void process (const GetCECVersion &msg, const Header &header); void process (const CECVersion &msg, const Header &header); From 925bdb8136889642cc77d507f5267edba1ce081d Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 15:52:36 -0400 Subject: [PATCH 38/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index d43367ab..56c52844 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -3023,7 +3023,7 @@ namespace WPEFramework libcecInitStatus++; //Acquire CEC Addresses - getPhysicalAddress(); + _instance->getPhysicalAddress(); smConnection = new Connection(LogicalAddress::UNREGISTERED,false,"ServiceManager::Connection::"); smConnection->open(); From 1f43996b685d09f67321bac5cc593956c00c3839 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:01:18 -0400 Subject: [PATCH 39/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 100 +++++++++++----------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 56c52844..75479b69 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -3061,7 +3061,7 @@ namespace WPEFramework void HdmiCecSinkImplementation::CECDisable(void) { std::lock_guard lock(m_enableMutex); - JsonObject params; + JsonObject params; LOGINFO("Entered CECDisable "); if(!cecEnableStatus) { @@ -3072,63 +3072,63 @@ namespace WPEFramework if(m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED) { stopArc(); - while(m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED) - { + while(m_currentArcRoutingState != ARC_STATE_ARC_TERMINATED) + { usleep(500000); - } + } } - LOGINFO(" CECDisable ARC stopped "); - cecEnableStatus = false; + LOGINFO(" CECDisable ARC stopped "); + cecEnableStatus = false; if (smConnection != NULL) { - LOGWARN("Stop Thread %p", smConnection ); - m_pollThreadExit = true; - m_ThreadExitCV.notify_one(); + LOGWARN("Stop Thread %p", smConnection ); + m_pollThreadExit = true; + m_ThreadExitCV.notify_one(); - try - { - if (m_pollThread.joinable()) - { - LOGWARN("Join Thread %p", smConnection ); - m_pollThread.join(); - } - } - catch(const std::system_error& e) - { - LOGERR("system_error exception in thread join %s", e.what()); - } - catch(const std::exception& e) - { - LOGERR("exception in thread join %s", e.what()); - } + try + { + if (m_pollThread.joinable()) + { + LOGWARN("Join Thread %p", smConnection ); + m_pollThread.join(); + } + } + catch(const std::system_error& e) + { + LOGERR("system_error exception in thread join %s", e.what()); + } + catch(const std::exception& e) + { + LOGERR("exception in thread join %s", e.what()); + } m_pollThreadState = POLL_THREAD_STATE_NONE; m_pollNextState = POLL_THREAD_STATE_NONE; - LOGWARN("Deleted Thread %p", smConnection ); + LOGWARN("Deleted Thread %p", smConnection ); smConnection->close(); delete smConnection; smConnection = NULL; } - m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; - m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; - if (m_audioStatusDetectionTimer.isActive()){ - m_audioStatusDetectionTimer.stop(); - } - m_isAudioStatusInfoUpdated = false; - m_audioStatusReceived = false; - m_audioStatusTimerStarted = false; - LOGINFO("CEC Disabled, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); + m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; + m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; + if (m_audioStatusDetectionTimer.isActive()){ + m_audioStatusDetectionTimer.stop(); + } + m_isAudioStatusInfoUpdated = false; + m_audioStatusReceived = false; + m_audioStatusTimerStarted = false; + LOGINFO("CEC Disabled, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); - for(int i=0; i< 16; i++) + for(int i=0; i< 16; i++) { - if (_instance->deviceList[i].m_isDevicePresent) - { - _instance->deviceList[i].clear(); - } + if (_instance->deviceList[i].m_isDevicePresent) + { + _instance->deviceList[i].clear(); + } } if(1 == libcecInitStatus) @@ -3145,18 +3145,18 @@ namespace WPEFramework } catch(...){ LOGWARN("Exception caught in LibCCEC::term"); - } + } - libcecInitStatus--; - LOGWARN("CEC Disabled %d",libcecInitStatus); - - params["cecEnable"] = string("false"); - std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); - while (index != _hdmiCecSinkNotifications.end()) { - (*index)->ReportCecEnabledEvent("false"); - index++; - } + libcecInitStatus--; + LOGWARN("CEC Disabled %d",libcecInitStatus); + params["cecEnable"] = string("false"); + std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); + while (index != _hdmiCecSinkNotifications.end()) { + (*index)->ReportCecEnabledEvent("false"); + index++; + } + } return; } From b273a4c419a5a43acb5596e00873af15dcb7b7a0 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:07:25 -0400 Subject: [PATCH 40/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 90 +++++++++++------------ 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 75479b69..b762b3b8 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -3341,7 +3341,7 @@ namespace WPEFramework return; } - SendKeyInfo keyInfo = {-1,-1}; + SendKeyInfo keyInfo = {-1,-1}; while(!_instance->m_sendKeyEventThreadExit) { @@ -3368,52 +3368,50 @@ namespace WPEFramework keyInfo = _instance->m_SendKeyQueue.front(); _instance->m_SendKeyQueue.pop(); - if(keyInfo.UserControl == "sendUserControlPressed" ) - { - LOGINFO("sendUserControlPressed : logical addr:0x%x keyCode: 0x%x queue size :%zu \n",keyInfo.logicalAddr,keyInfo.keyCode,_instance->m_SendKeyQueue.size()); - _instance->sendUserControlPressed(keyInfo.logicalAddr,keyInfo.keyCode); - } - else if(keyInfo.UserControl == "sendUserControlReleased") - { - LOGINFO("sendUserControlReleased : logical addr:0x%x queue size :%zu \n",keyInfo.logicalAddr,_instance->m_SendKeyQueue.size()); - _instance->sendUserControlReleased(keyInfo.logicalAddr); - } - else - { - LOGINFO("sendKeyPressEvent : logical addr:0x%x keyCode: 0x%x queue size :%zu \n",keyInfo.logicalAddr,keyInfo.keyCode,_instance->m_SendKeyQueue.size()); - _instance->sendKeyPressEvent(keyInfo.logicalAddr,keyInfo.keyCode); - _instance->sendKeyReleaseEvent(keyInfo.logicalAddr); - } - - if((_instance->m_SendKeyQueue.size()<=1 || (_instance->m_SendKeyQueue.size() % 2 == 0)) && ((keyInfo.keyCode == VOLUME_UP) || (keyInfo.keyCode == VOLUME_DOWN) || (keyInfo.keyCode == MUTE)) ) - { - if(keyInfo.keyCode == MUTE) - { - _instance->sendGiveAudioStatusMsg(); - } - else - { - LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ",_instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); - if (!_instance->m_isAudioStatusInfoUpdated) - { - if ( !(_instance->m_audioStatusDetectionTimer.isActive())) - { - LOGINFO("Audio status info not updated. Starting the Timer!"); - _instance->m_audioStatusTimerStarted = true; - _instance->m_audioStatusDetectionTimer.start((HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS)); - } - LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", _instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); - } - else - { - if (!_instance->m_audioStatusReceived){ - _instance->sendGiveAudioStatusMsg(); - } - } - } - } - } + if(keyInfo.UserControl == "sendUserControlPressed" ) + { + LOGINFO("sendUserControlPressed : logical addr:0x%x keyCode: 0x%x queue size :%zu \n",keyInfo.logicalAddr,keyInfo.keyCode,_instance->m_SendKeyQueue.size()); + _instance->sendUserControlPressed(keyInfo.logicalAddr,keyInfo.keyCode); + } + else if(keyInfo.UserControl == "sendUserControlReleased") + { + LOGINFO("sendUserControlReleased : logical addr:0x%x queue size :%zu \n",keyInfo.logicalAddr,_instance->m_SendKeyQueue.size()); + _instance->sendUserControlReleased(keyInfo.logicalAddr); + } + else + { + LOGINFO("sendKeyPressEvent : logical addr:0x%x keyCode: 0x%x queue size :%zu \n",keyInfo.logicalAddr,keyInfo.keyCode,_instance->m_SendKeyQueue.size()); + _instance->sendKeyPressEvent(keyInfo.logicalAddr,keyInfo.keyCode); + _instance->sendKeyReleaseEvent(keyInfo.logicalAddr); + } + if((_instance->m_SendKeyQueue.size()<=1 || (_instance->m_SendKeyQueue.size() % 2 == 0)) && ((keyInfo.keyCode == VOLUME_UP) || (keyInfo.keyCode == VOLUME_DOWN) || (keyInfo.keyCode == MUTE)) ) + { + if(keyInfo.keyCode == MUTE) + { + _instance->sendGiveAudioStatusMsg(); + } + else + { + LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ",_instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); + if (!_instance->m_isAudioStatusInfoUpdated) + { + if ( !(_instance->m_audioStatusDetectionTimer.isActive())) + { + LOGINFO("Audio status info not updated. Starting the Timer!"); + _instance->m_audioStatusTimerStarted = true; + _instance->m_audioStatusDetectionTimer.start((HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS)); + } + LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", _instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); + } + else + { + if (!_instance->m_audioStatusReceived){ + _instance->sendGiveAudioStatusMsg(); + } + } + } + } }//while(!_instance->m_sendKeyEventThreadExit) }//threadSendKeyEvent From 01934ecb3f78b64206274b71ba40126b0179caa0 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:08:09 -0400 Subject: [PATCH 41/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 132 +++++++++++----------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index b762b3b8..7b4bd786 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -79,8 +79,8 @@ #define CEC_SETTING_VENDOR_ID "cecVendorId" enum { - DEVICE_POWER_STATE_ON = 0, - DEVICE_POWER_STATE_OFF = 1 + DEVICE_POWER_STATE_ON = 0, + DEVICE_POWER_STATE_OFF = 1 }; static std::vector defaultVendorId = {0x00,0x19,0xFB}; @@ -677,8 +677,8 @@ namespace WPEFramework m_isHdmiInConnected = false; hdmiCecAudioDeviceConnected = false; m_isAudioStatusInfoUpdated = false; - m_audioStatusReceived = false; - m_audioStatusTimerStarted = false; + m_audioStatusReceived = false; + m_audioStatusTimerStarted = false; m_audioDevicePowerStatusRequested = false; m_pollNextState = POLL_THREAD_STATE_NONE; m_pollThreadState = POLL_THREAD_STATE_NONE; @@ -702,7 +702,7 @@ namespace WPEFramework m_arcRoutingThread = std::thread(threadArcRouting); m_audioStatusDetectionTimer.connect( std::bind( &HdmiCecSinkImplementation::audioStatusTimerFunction, this ) ); - m_audioStatusDetectionTimer.setSingleShot(true); + m_audioStatusDetectionTimer.setSingleShot(true); m_arcStartStopTimer.connect( std::bind( &HdmiCecSinkImplementation::arcStartStopTimerFunction, this ) ); m_arcStartStopTimer.setSingleShot(true); @@ -2476,12 +2476,12 @@ namespace WPEFramework hdmiCecAudioDeviceConnected = false; if (m_audioStatusDetectionTimer.isActive()){ - m_audioStatusDetectionTimer.stop(); - } - m_isAudioStatusInfoUpdated = false; - m_audioStatusReceived = false; - m_audioStatusTimerStarted = false; - LOGINFO("Audio device removed, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); + m_audioStatusDetectionTimer.stop(); + } + m_isAudioStatusInfoUpdated = false; + m_audioStatusReceived = false; + m_audioStatusTimerStarted = false; + LOGINFO("Audio device removed, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); std::list::const_iterator index(_hdmiCecSinkNotifications.begin()); while (index != _hdmiCecSinkNotifications.end()) { (*index)->ReportAudioDeviceConnectedStatus("success", "false"); @@ -2739,41 +2739,41 @@ namespace WPEFramework { try{ - logicalAddress = LogicalAddress(_instance->m_logicalAddressAllocated); - LibCCEC::getInstance().addLogicalAddress(logicalAddress); - _instance->smConnection->setSource(logicalAddress); - _instance->m_numberOfDevices = 0; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType = DeviceType::TV; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_isDevicePresent = true; - _instance->deviceList[_instance->m_logicalAddressAllocated].update(physical_addr); - _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_1_4; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_vendorID = appVendorId; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus = PowerStatus(powerState); - _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage = defaultLanguage; - _instance->deviceList[_instance->m_logicalAddressAllocated].m_osdName = osdName.toString().c_str(); - if(cecVersion == 2.0) { - _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_2_0; - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), + logicalAddress = LogicalAddress(_instance->m_logicalAddressAllocated); + LibCCEC::getInstance().addLogicalAddress(logicalAddress); + _instance->smConnection->setSource(logicalAddress); + _instance->m_numberOfDevices = 0; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType = DeviceType::TV; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_isDevicePresent = true; + _instance->deviceList[_instance->m_logicalAddressAllocated].update(physical_addr); + _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_1_4; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_vendorID = appVendorId; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_powerStatus = PowerStatus(powerState); + _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage = defaultLanguage; + _instance->deviceList[_instance->m_logicalAddressAllocated].m_osdName = osdName.toString().c_str(); + if(cecVersion == 2.0) { + _instance->deviceList[_instance->m_logicalAddressAllocated].m_cecVersion = Version::V_2_0; + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), MessageEncoder().encode(ReportFeatures(Version::V_2_0,allDevicetype,rcProfile,deviceFeatures)), 500); - } - _instance->smConnection->addFrameListener(_instance->msgFrameListener); - _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), - MessageEncoder().encode(ReportPhysicalAddress(physical_addr, _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType)), 100); + } + _instance->smConnection->addFrameListener(_instance->msgFrameListener); + _instance->smConnection->sendTo(LogicalAddress(LogicalAddress::BROADCAST), + MessageEncoder().encode(ReportPhysicalAddress(physical_addr, _instance->deviceList[_instance->m_logicalAddressAllocated].m_deviceType)), 100); - _instance->m_sleepTime = 0; - _instance->m_pollThreadState = POLL_THREAD_STATE_PING; + _instance->m_sleepTime = 0; + _instance->m_pollThreadState = POLL_THREAD_STATE_PING; } catch(InvalidStateException &e){ LOGWARN("InvalidStateException caught while allocated logical address. %s", e.what()); - _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; + _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; } catch(IOException &e){ LOGWARN("IOException caught while allocated logical address. %s", e.what()); - _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; + _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; } catch(...){ LOGWARN("Exception caught while allocated logical address."); - _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; + _instance->m_pollThreadState = POLL_THREAD_STATE_EXIT; } } else @@ -3116,12 +3116,12 @@ namespace WPEFramework m_logicalAddressAllocated = LogicalAddress::UNREGISTERED; m_currentArcRoutingState = ARC_STATE_ARC_TERMINATED; if (m_audioStatusDetectionTimer.isActive()){ - m_audioStatusDetectionTimer.stop(); - } - m_isAudioStatusInfoUpdated = false; - m_audioStatusReceived = false; - m_audioStatusTimerStarted = false; - LOGINFO("CEC Disabled, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); + m_audioStatusDetectionTimer.stop(); + } + m_isAudioStatusInfoUpdated = false; + m_audioStatusReceived = false; + m_audioStatusTimerStarted = false; + LOGINFO("CEC Disabled, reset the audio status info. m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); for(int i=0; i< 16; i++) { @@ -3389,40 +3389,40 @@ namespace WPEFramework { if(keyInfo.keyCode == MUTE) { - _instance->sendGiveAudioStatusMsg(); + _instance->sendGiveAudioStatusMsg(); } else { - LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ",_instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); - if (!_instance->m_isAudioStatusInfoUpdated) - { - if ( !(_instance->m_audioStatusDetectionTimer.isActive())) - { - LOGINFO("Audio status info not updated. Starting the Timer!"); - _instance->m_audioStatusTimerStarted = true; - _instance->m_audioStatusDetectionTimer.start((HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS)); - } - LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", _instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); - } - else - { - if (!_instance->m_audioStatusReceived){ - _instance->sendGiveAudioStatusMsg(); - } - } + LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ",_instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); + if (!_instance->m_isAudioStatusInfoUpdated) + { + if ( !(_instance->m_audioStatusDetectionTimer.isActive())) + { + LOGINFO("Audio status info not updated. Starting the Timer!"); + _instance->m_audioStatusTimerStarted = true; + _instance->m_audioStatusDetectionTimer.start((HDMICECSINK_UPDATE_AUDIO_STATUS_INTERVAL_MS)); + } + LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", _instance->m_isAudioStatusInfoUpdated,_instance->m_audioStatusReceived,_instance->m_audioStatusTimerStarted); + } + else + { + if (!_instance->m_audioStatusReceived){ + _instance->sendGiveAudioStatusMsg(); + } + } } } }//while(!_instance->m_sendKeyEventThreadExit) }//threadSendKeyEvent void HdmiCecSinkImplementation::audioStatusTimerFunction() - { - m_audioStatusTimerStarted = false; - m_isAudioStatusInfoUpdated = true; - LOGINFO("Timer Expired. Requesting the AudioStatus since not received.\n"); - sendGiveAudioStatusMsg(); - LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); - } + { + m_audioStatusTimerStarted = false; + m_isAudioStatusInfoUpdated = true; + LOGINFO("Timer Expired. Requesting the AudioStatus since not received.\n"); + sendGiveAudioStatusMsg(); + LOGINFO("m_isAudioStatusInfoUpdated :%d, m_audioStatusReceived :%d, m_audioStatusTimerStarted:%d ", m_isAudioStatusInfoUpdated,m_audioStatusReceived,m_audioStatusTimerStarted); + } void HdmiCecSinkImplementation::threadArcRouting() From e1a31901f63ba037366652746ed58d87fa784113 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Mon, 2 Jun 2025 16:11:48 -0400 Subject: [PATCH 42/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSource/HdmiCecSourceImplementation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSource/HdmiCecSourceImplementation.h b/HdmiCecSource/HdmiCecSourceImplementation.h index 6239dab5..a5936907 100644 --- a/HdmiCecSource/HdmiCecSourceImplementation.h +++ b/HdmiCecSource/HdmiCecSourceImplementation.h @@ -68,7 +68,7 @@ namespace WPEFramework { void process (const InActiveSource &msg, const Header &header); void process (const ImageViewOn &msg, const Header &header); void process (const TextViewOn &msg, const Header &header); - void process (const RequestActiveSource &msg, const Header &header); + void process (const RequestActiveSourceMessage &msg, const Header &header); void process (const Standby &msg, const Header &header); void process (const GetCECVersion &msg, const Header &header); void process (const CECVersion &msg, const Header &header); From 3da36f777250adc896d1c9763eee27bf6cdfb295 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:36:26 -0400 Subject: [PATCH 43/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.cpp | 26 +- HdmiCecSink/HdmiCecSinkImplementation.cpp | 13 + HdmiCecSink/HdmiCecSinkImplementation.h | 1010 ++++++++++----------- 3 files changed, 531 insertions(+), 518 deletions(-) diff --git a/HdmiCecSink/HdmiCecSink.cpp b/HdmiCecSink/HdmiCecSink.cpp index edb90f90..a7e08588 100644 --- a/HdmiCecSink/HdmiCecSink.cpp +++ b/HdmiCecSink/HdmiCecSink.cpp @@ -34,7 +34,7 @@ namespace WPEFramework { - namespace { + namespace { static Plugin::Metadata metadata( // Version (Major, Minor, Patch) @@ -54,13 +54,13 @@ namespace WPEFramework const std::string HdmiCecSink::Initialize(PluginHost::IShell *service) { - profileType = searchRdkProfile(); + profileType = searchRdkProfile(); - if (profileType == STB || profileType == NOT_FOUND) - { - LOGINFO("Invalid profile type for TV \n"); - return (std::string("Not supported")); - } + if (profileType == STB || profileType == NOT_FOUND) + { + LOGINFO("Invalid profile type for TV \n"); + return (std::string("Not supported")); + } string msg = ""; @@ -101,13 +101,13 @@ namespace WPEFramework void HdmiCecSink::Deinitialize(PluginHost::IShell* /* service */) { - profileType = searchRdkProfile(); + profileType = searchRdkProfile(); - if (profileType == STB || profileType == NOT_FOUND) - { - LOGINFO("Invalid profile type for TV \n"); - return ; - } + if (profileType == STB || profileType == NOT_FOUND) + { + LOGINFO("Invalid profile type for TV \n"); + return ; + } bool enabled = false; bool ret = false; diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 7b4bd786..334f96c4 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -1603,6 +1603,19 @@ namespace WPEFramework return Core::ERROR_NONE; } + Core::hresult HdmiCecSink::setMenuLanguage(const string &language, HdmiCecSinkSuccess &success) + { + std::string lang; + + lang = language; + + setCurrentLanguage(Language(lang.data())); + success.success = true; + + return Core::ERROR_NONE; + + } + Core::hresult HdmiCecSinkImplementation::SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) { diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 0babdf7f..77bb940f 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -66,37 +66,37 @@ namespace WPEFramework { public: HdmiCecSinkProcessor(Connection &conn) : conn(conn) {} void process (const ActiveSource &msg, const Header &header); - void process (const InActiveSource &msg, const Header &header); - void process (const ImageViewOn &msg, const Header &header); - void process (const TextViewOn &msg, const Header &header); - void process (const RequestActiveSourceMessage &msg, const Header &header); - void process (const Standby &msg, const Header &header); - void process (const GetCECVersion &msg, const Header &header); - void process (const CECVersion &msg, const Header &header); - void process (const SetMenuLanguage &msg, const Header &header); - void process (const GiveOSDName &msg, const Header &header); - void process (const GivePhysicalAddress &msg, const Header &header); - void process (const GiveDeviceVendorID &msg, const Header &header); - void process (const SetOSDString &msg, const Header &header); - void process (const SetOSDName &msg, const Header &header); - void process (const RoutingChange &msg, const Header &header); - void process (const RoutingInformation &msg, const Header &header); - void process (const SetStreamPath &msg, const Header &header); - void process (const GetMenuLanguage &msg, const Header &header); - void process (const ReportPhysicalAddress &msg, const Header &header); + void process (const InActiveSource &msg, const Header &header); + void process (const ImageViewOn &msg, const Header &header); + void process (const TextViewOn &msg, const Header &header); + void process (const RequestActiveSourceMessage &msg, const Header &header); + void process (const Standby &msg, const Header &header); + void process (const GetCECVersion &msg, const Header &header); + void process (const CECVersion &msg, const Header &header); + void process (const SetMenuLanguage &msg, const Header &header); + void process (const GiveOSDName &msg, const Header &header); + void process (const GivePhysicalAddress &msg, const Header &header); + void process (const GiveDeviceVendorID &msg, const Header &header); + void process (const SetOSDString &msg, const Header &header); + void process (const SetOSDName &msg, const Header &header); + void process (const RoutingChange &msg, const Header &header); + void process (const RoutingInformation &msg, const Header &header); + void process (const SetStreamPath &msg, const Header &header); + void process (const GetMenuLanguage &msg, const Header &header); + void process (const ReportPhysicalAddress &msg, const Header &header); void process (const DeviceVendorID &msg, const Header &header); - void process (const GiveDevicePowerStatus &msg, const Header &header); - void process (const ReportPowerStatus &msg, const Header &header); - void process (const FeatureAbort &msg, const Header &header); - void process (const Abort &msg, const Header &header); - void process (const Polling &msg, const Header &header); + void process (const GiveDevicePowerStatus &msg, const Header &header); + void process (const ReportPowerStatus &msg, const Header &header); + void process (const FeatureAbort &msg, const Header &header); + void process (const Abort &msg, const Header &header); + void process (const Polling &msg, const Header &header); void process (const InitiateArc &msg, const Header &header); void process (const TerminateArc &msg, const Header &header); void process (const ReportShortAudioDescriptor &msg, const Header &header); - void process (const SetSystemAudioMode &msg, const Header &header); - void process (const ReportAudioStatus &msg, const Header &header); - void process (const GiveFeatures &msg, const Header &header); - void process (const RequestCurrentLatency &msg, const Header &header); + void process (const SetSystemAudioMode &msg, const Header &header); + void process (const ReportAudioStatus &msg, const Header &header); + void process (const GiveFeatures &msg, const Header &header); + void process (const RequestCurrentLatency &msg, const Header &header); private: Connection conn; void printHeader(const Header &header) @@ -107,284 +107,284 @@ namespace WPEFramework { }; - class CECDeviceParams { - public: - - enum { - REQUEST_NONE = 0, - REQUEST_PHISICAL_ADDRESS = 1, - REQUEST_CEC_VERSION, - REQUEST_DEVICE_VENDOR_ID, - REQUEST_POWER_STATUS, - REQUEST_OSD_NAME, - }; - - enum { - REQUEST_DONE = 0, - REQUEST_NOT_DONE, - REQUEST_TIME_ELAPSED, - }; - - DeviceType m_deviceType; - LogicalAddress m_logicalAddress; - PhysicalAddress m_physicalAddr; - Version m_cecVersion; - VendorID m_vendorID; - OSDName m_osdName; - PowerStatus m_powerStatus; - bool m_isDevicePresent; - bool m_isDeviceDisconnected; - Language m_currentLanguage; - bool m_isActiveSource; - bool m_isDeviceTypeUpdated; - bool m_isPAUpdated; - bool m_isVersionUpdated; - bool m_isOSDNameUpdated; - bool m_isVendorIDUpdated; - bool m_isPowerStatusUpdated; - int m_isRequested; - int m_isRequestRetry; - std::chrono::system_clock::time_point m_requestTime; - std::vector m_featureAborts; - std::chrono::system_clock::time_point m_lastPowerUpdateTime; - - CECDeviceParams() - : m_deviceType(0), m_logicalAddress(0),m_physicalAddr(0x0f,0x0f,0x0f,0x0f),m_cecVersion(0),m_vendorID(0,0,0),m_osdName(""),m_powerStatus(0),m_currentLanguage("") - { - m_isDevicePresent = false; - m_isActiveSource = false; - m_isPAUpdated = false; - m_isVersionUpdated = false; - m_isOSDNameUpdated = false; - m_isVendorIDUpdated = false; - m_isPowerStatusUpdated = false; - m_isDeviceDisconnected = false; - m_isDeviceTypeUpdated = false; - m_isRequestRetry = 0; - } - - void clear( ) - { - m_deviceType = 0; - m_logicalAddress = 0; - m_physicalAddr = PhysicalAddress(0x0f,0x0f,0x0f,0x0f); - m_cecVersion = 0; - m_vendorID = VendorID(0,0,0); - m_osdName = ""; - m_powerStatus = 0; - m_currentLanguage = ""; - m_isDevicePresent = false; - m_isActiveSource = false; - m_isPAUpdated = false; - m_isVersionUpdated = false; - m_isOSDNameUpdated = false; - m_isVendorIDUpdated = false; - m_isPowerStatusUpdated = false; - m_isDeviceDisconnected = false; - m_isDeviceTypeUpdated = false; - } - - void printVariable() - { - LOGWARN("Device LogicalAddress %s", m_logicalAddress.toString().c_str()); - LOGWARN("Device Type %s", m_deviceType.toString().c_str()); - LOGWARN("Device Present %d", m_isDevicePresent); - LOGWARN("Active Source %d", m_isActiveSource); - LOGWARN("PA Updated %d", m_isPAUpdated); - LOGWARN("Version Updated %d", m_isVersionUpdated); - LOGWARN("OSDName Updated %d", m_isOSDNameUpdated); - LOGWARN("PowerStatus Updated %d", m_isPowerStatusUpdated); - LOGWARN("VendorID Updated %d", m_isPowerStatusUpdated); - LOGWARN("CEC Version : %s", m_cecVersion.toString().c_str()); - LOGWARN("Vendor ID : %s", m_vendorID.toString().c_str()); - LOGWARN("PhisicalAddress : %s", m_physicalAddr.toString().c_str()); - LOGWARN("OSDName : %s", m_osdName.toString().c_str()); - LOGWARN("Power Status : %s", m_powerStatus.toString().c_str()); - LOGWARN("Language : %s", m_currentLanguage.toString().c_str()); - } - - bool isAllUpdated() { - if( !m_isPAUpdated - || !m_isVersionUpdated - || !m_isOSDNameUpdated - || !m_isVendorIDUpdated - || !m_isPowerStatusUpdated - || !m_isDeviceTypeUpdated ){ - return false; - } - return true; - } - - void update( const DeviceType &deviceType ) { - m_deviceType = deviceType; - m_isDeviceTypeUpdated = true; - } - - void update( const PhysicalAddress &physical_addr ) { - m_physicalAddr = physical_addr; - m_isPAUpdated = true; - } - - void update ( const VendorID &vendorId) { - m_vendorID = vendorId; - m_isVendorIDUpdated = true; - } - - void update ( const Version &version ) { - m_cecVersion = version; - m_isVersionUpdated = true; - } - - void update ( const OSDName &osdName ) { - m_osdName = osdName; - m_isOSDNameUpdated = true; - } - - void update ( const PowerStatus &status ) { - m_powerStatus = status; - m_isPowerStatusUpdated = true; - m_lastPowerUpdateTime = std::chrono::system_clock::now(); - } - }; - - class DeviceNode { - public: - uint8_t m_childsLogicalAddr[LogicalAddress::UNREGISTERED]; - - DeviceNode() { - int i; - for (i = 0; i < LogicalAddress::UNREGISTERED; i++ ) - { - m_childsLogicalAddr[i] = LogicalAddress::UNREGISTERED; - } - } - - } ; - typedef struct sendKeyInfo + class CECDeviceParams { + public: + + enum { + REQUEST_NONE = 0, + REQUEST_PHISICAL_ADDRESS = 1, + REQUEST_CEC_VERSION, + REQUEST_DEVICE_VENDOR_ID, + REQUEST_POWER_STATUS, + REQUEST_OSD_NAME, + }; + + enum { + REQUEST_DONE = 0, + REQUEST_NOT_DONE, + REQUEST_TIME_ELAPSED, + }; + + DeviceType m_deviceType; + LogicalAddress m_logicalAddress; + PhysicalAddress m_physicalAddr; + Version m_cecVersion; + VendorID m_vendorID; + OSDName m_osdName; + PowerStatus m_powerStatus; + bool m_isDevicePresent; + bool m_isDeviceDisconnected; + Language m_currentLanguage; + bool m_isActiveSource; + bool m_isDeviceTypeUpdated; + bool m_isPAUpdated; + bool m_isVersionUpdated; + bool m_isOSDNameUpdated; + bool m_isVendorIDUpdated; + bool m_isPowerStatusUpdated; + int m_isRequested; + int m_isRequestRetry; + std::chrono::system_clock::time_point m_requestTime; + std::vector m_featureAborts; + std::chrono::system_clock::time_point m_lastPowerUpdateTime; + + CECDeviceParams() + : m_deviceType(0), m_logicalAddress(0),m_physicalAddr(0x0f,0x0f,0x0f,0x0f),m_cecVersion(0),m_vendorID(0,0,0),m_osdName(""),m_powerStatus(0),m_currentLanguage("") + { + m_isDevicePresent = false; + m_isActiveSource = false; + m_isPAUpdated = false; + m_isVersionUpdated = false; + m_isOSDNameUpdated = false; + m_isVendorIDUpdated = false; + m_isPowerStatusUpdated = false; + m_isDeviceDisconnected = false; + m_isDeviceTypeUpdated = false; + m_isRequestRetry = 0; + } + + void clear( ) + { + m_deviceType = 0; + m_logicalAddress = 0; + m_physicalAddr = PhysicalAddress(0x0f,0x0f,0x0f,0x0f); + m_cecVersion = 0; + m_vendorID = VendorID(0,0,0); + m_osdName = ""; + m_powerStatus = 0; + m_currentLanguage = ""; + m_isDevicePresent = false; + m_isActiveSource = false; + m_isPAUpdated = false; + m_isVersionUpdated = false; + m_isOSDNameUpdated = false; + m_isVendorIDUpdated = false; + m_isPowerStatusUpdated = false; + m_isDeviceDisconnected = false; + m_isDeviceTypeUpdated = false; + } + + void printVariable() + { + LOGWARN("Device LogicalAddress %s", m_logicalAddress.toString().c_str()); + LOGWARN("Device Type %s", m_deviceType.toString().c_str()); + LOGWARN("Device Present %d", m_isDevicePresent); + LOGWARN("Active Source %d", m_isActiveSource); + LOGWARN("PA Updated %d", m_isPAUpdated); + LOGWARN("Version Updated %d", m_isVersionUpdated); + LOGWARN("OSDName Updated %d", m_isOSDNameUpdated); + LOGWARN("PowerStatus Updated %d", m_isPowerStatusUpdated); + LOGWARN("VendorID Updated %d", m_isPowerStatusUpdated); + LOGWARN("CEC Version : %s", m_cecVersion.toString().c_str()); + LOGWARN("Vendor ID : %s", m_vendorID.toString().c_str()); + LOGWARN("PhisicalAddress : %s", m_physicalAddr.toString().c_str()); + LOGWARN("OSDName : %s", m_osdName.toString().c_str()); + LOGWARN("Power Status : %s", m_powerStatus.toString().c_str()); + LOGWARN("Language : %s", m_currentLanguage.toString().c_str()); + } + + bool isAllUpdated() { + if( !m_isPAUpdated + || !m_isVersionUpdated + || !m_isOSDNameUpdated + || !m_isVendorIDUpdated + || !m_isPowerStatusUpdated + || !m_isDeviceTypeUpdated ){ + return false; + } + return true; + } + + void update( const DeviceType &deviceType ) { + m_deviceType = deviceType; + m_isDeviceTypeUpdated = true; + } + + void update( const PhysicalAddress &physical_addr ) { + m_physicalAddr = physical_addr; + m_isPAUpdated = true; + } + + void update ( const VendorID &vendorId) { + m_vendorID = vendorId; + m_isVendorIDUpdated = true; + } + + void update ( const Version &version ) { + m_cecVersion = version; + m_isVersionUpdated = true; + } + + void update ( const OSDName &osdName ) { + m_osdName = osdName; + m_isOSDNameUpdated = true; + } + + void update ( const PowerStatus &status ) { + m_powerStatus = status; + m_isPowerStatusUpdated = true; + m_lastPowerUpdateTime = std::chrono::system_clock::now(); + } + }; + + class DeviceNode { + public: + uint8_t m_childsLogicalAddr[LogicalAddress::UNREGISTERED]; + + DeviceNode() { + int i; + for (i = 0; i < LogicalAddress::UNREGISTERED; i++ ) + { + m_childsLogicalAddr[i] = LogicalAddress::UNREGISTERED; + } + } + + } ; + typedef struct sendKeyInfo { int logicalAddr; int keyCode; - string UserControl; + string UserControl; }SendKeyInfo; - class HdmiPortMap { - public: - uint8_t m_portID; - bool m_isConnected; - LogicalAddress m_logicalAddr; - PhysicalAddress m_physicalAddr; - DeviceNode m_deviceChain[3]; - - HdmiPortMap(uint8_t portID) : m_portID(portID), - m_logicalAddr(LogicalAddress::UNREGISTERED), - m_physicalAddr(portID+1,0,0,0) - { - m_isConnected = false; - } - - void update(bool isConnected) - { - m_isConnected = isConnected; - } - - void update( const LogicalAddress &addr ) - { - m_logicalAddr = addr; - } - - void addChild( const LogicalAddress &logical_addr, const PhysicalAddress &physical_addr ) - { - LOGINFO(" logicalAddr = %d, phisicalAddr = %s", m_logicalAddr.toInt(), physical_addr.toString().c_str()); - - if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED && - m_logicalAddr.toInt() != logical_addr.toInt() ) - { - LOGINFO(" update own logicalAddr = %d, new devcie logicalAddress = %d", m_logicalAddr.toInt(), logical_addr.toInt() ); - /* check matching with this port's physical address */ - if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && - physical_addr.getByteValue(1) != 0 ) - { - if ( physical_addr.getByteValue(3) != 0 ) - { - m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1] = logical_addr.toInt(); - } - else if ( physical_addr.getByteValue(2) != 0 ) - { - m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1] = logical_addr.toInt(); - } - else if ( physical_addr.getByteValue(1) != 0 ) - { - m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1] = logical_addr.toInt(); - } - } - } - else if ( physical_addr == m_physicalAddr ) - { - update(logical_addr); - LOGINFO(" update own logicalAddr = %d", m_logicalAddr.toInt()); - } - } - - void removeChild( PhysicalAddress &physical_addr ) - { - if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED ) - { - /* check matching with this port's physical address */ - if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && - physical_addr.getByteValue(1) != 0 ) - { - if ( physical_addr.getByteValue(3) != 0 ) - { - m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1] = LogicalAddress::UNREGISTERED; - } - else if ( physical_addr.getByteValue(2) != 0 ) - { - m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1] = LogicalAddress::UNREGISTERED; - } - else if ( physical_addr.getByteValue(1) != 0 ) - { - m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1] = LogicalAddress::UNREGISTERED; - } - } - } - } - - void getRoute( PhysicalAddress &physical_addr, std::vector & route ) - { - LOGINFO(" logicalAddr = %d, phsical = %s", m_logicalAddr.toInt(), physical_addr.toString().c_str()); - - if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED ) - { - LOGINFO(" search for logicalAddr = %d", m_logicalAddr.toInt()); - /* check matching with this port's physical address */ - if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && - physical_addr.getByteValue(1) != 0 ) - { - if ( physical_addr.getByteValue(3) != 0 ) - { - route.push_back(m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1]); - } - - if ( physical_addr.getByteValue(2) != 0 ) - { - route.push_back(m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1]); - } - - if ( physical_addr.getByteValue(1) != 0 ) - { - route.push_back(m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1]); - } - - route.push_back(m_logicalAddr.toInt()); - } - else - { - route.push_back(m_logicalAddr.toInt()); - LOGINFO("logicalAddr = %d, physical = %s", m_logicalAddr.toInt(), m_physicalAddr.toString().c_str()); - } - } - } - }; + class HdmiPortMap { + public: + uint8_t m_portID; + bool m_isConnected; + LogicalAddress m_logicalAddr; + PhysicalAddress m_physicalAddr; + DeviceNode m_deviceChain[3]; + + HdmiPortMap(uint8_t portID) : m_portID(portID), + m_logicalAddr(LogicalAddress::UNREGISTERED), + m_physicalAddr(portID+1,0,0,0) + { + m_isConnected = false; + } + + void update(bool isConnected) + { + m_isConnected = isConnected; + } + + void update( const LogicalAddress &addr ) + { + m_logicalAddr = addr; + } + + void addChild( const LogicalAddress &logical_addr, const PhysicalAddress &physical_addr ) + { + LOGINFO(" logicalAddr = %d, phisicalAddr = %s", m_logicalAddr.toInt(), physical_addr.toString().c_str()); + + if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED && + m_logicalAddr.toInt() != logical_addr.toInt() ) + { + LOGINFO(" update own logicalAddr = %d, new devcie logicalAddress = %d", m_logicalAddr.toInt(), logical_addr.toInt() ); + /* check matching with this port's physical address */ + if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && + physical_addr.getByteValue(1) != 0 ) + { + if ( physical_addr.getByteValue(3) != 0 ) + { + m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1] = logical_addr.toInt(); + } + else if ( physical_addr.getByteValue(2) != 0 ) + { + m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1] = logical_addr.toInt(); + } + else if ( physical_addr.getByteValue(1) != 0 ) + { + m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1] = logical_addr.toInt(); + } + } + } + else if ( physical_addr == m_physicalAddr ) + { + update(logical_addr); + LOGINFO(" update own logicalAddr = %d", m_logicalAddr.toInt()); + } + } + + void removeChild( PhysicalAddress &physical_addr ) + { + if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED ) + { + /* check matching with this port's physical address */ + if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && + physical_addr.getByteValue(1) != 0 ) + { + if ( physical_addr.getByteValue(3) != 0 ) + { + m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1] = LogicalAddress::UNREGISTERED; + } + else if ( physical_addr.getByteValue(2) != 0 ) + { + m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1] = LogicalAddress::UNREGISTERED; + } + else if ( physical_addr.getByteValue(1) != 0 ) + { + m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1] = LogicalAddress::UNREGISTERED; + } + } + } + } + + void getRoute( PhysicalAddress &physical_addr, std::vector & route ) + { + LOGINFO(" logicalAddr = %d, phsical = %s", m_logicalAddr.toInt(), physical_addr.toString().c_str()); + + if ( m_logicalAddr.toInt() != LogicalAddress::UNREGISTERED ) + { + LOGINFO(" search for logicalAddr = %d", m_logicalAddr.toInt()); + /* check matching with this port's physical address */ + if( physical_addr.getByteValue(0) == m_physicalAddr.getByteValue(0) && + physical_addr.getByteValue(1) != 0 ) + { + if ( physical_addr.getByteValue(3) != 0 ) + { + route.push_back(m_deviceChain[2].m_childsLogicalAddr[physical_addr.getByteValue(3) - 1]); + } + + if ( physical_addr.getByteValue(2) != 0 ) + { + route.push_back(m_deviceChain[1].m_childsLogicalAddr[physical_addr.getByteValue(2) - 1]); + } + + if ( physical_addr.getByteValue(1) != 0 ) + { + route.push_back(m_deviceChain[0].m_childsLogicalAddr[physical_addr.getByteValue(1) - 1]); + } + + route.push_back(m_logicalAddr.toInt()); + } + else + { + route.push_back(m_logicalAddr.toInt()); + LOGINFO("logicalAddr = %d, physical = %s", m_logicalAddr.toInt(), m_physicalAddr.toString().c_str()); + } + } + } + }; class binary_semaphore { @@ -471,83 +471,83 @@ namespace WPEFramework { std::condition_variable cv_; }; - // This is a server for a JSONRPC communication channel. - // For a plugin to be capable to handle JSONRPC, inherit from PluginHost::JSONRPC. - // By inheriting from this class, the plugin realizes the interface PluginHost::IDispatcher. - // This realization of this interface implements, by default, the following methods on this plugin - // - exists - // - register - // - unregister - // Any other methood to be handled by this plugin can be added can be added by using the - // templated methods Register on the PluginHost::JSONRPC class. - // As the registration/unregistration of notifications is realized by the class PluginHost::JSONRPC, - // this class exposes a public method called, Notify(), using this methods, all subscribed clients - // will receive a JSONRPC message as a notification, in case this method is called. + // This is a server for a JSONRPC communication channel. + // For a plugin to be capable to handle JSONRPC, inherit from PluginHost::JSONRPC. + // By inheriting from this class, the plugin realizes the interface PluginHost::IDispatcher. + // This realization of this interface implements, by default, the following methods on this plugin + // - exists + // - register + // - unregister + // Any other methood to be handled by this plugin can be added can be added by using the + // templated methods Register on the PluginHost::JSONRPC class. + // As the registration/unregistration of notifications is realized by the class PluginHost::JSONRPC, + // this class exposes a public method called, Notify(), using this methods, all subscribed clients + // will receive a JSONRPC message as a notification, in case this method is called. class HdmiCecSinkImplementation : public Exchange::IHdmiCecSink { - enum { - POLL_THREAD_STATE_NONE, - POLL_THREAD_STATE_IDLE, - POLL_THREAD_STATE_POLL, - POLL_THREAD_STATE_PING, - POLL_THREAD_STATE_INFO, - POLL_THREAD_STATE_WAIT, - POLL_THREAD_STATE_CLEAN, - POLL_THREAD_STATE_UPDATE, - POLL_THREAD_STATE_EXIT, - }; + enum { + POLL_THREAD_STATE_NONE, + POLL_THREAD_STATE_IDLE, + POLL_THREAD_STATE_POLL, + POLL_THREAD_STATE_PING, + POLL_THREAD_STATE_INFO, + POLL_THREAD_STATE_WAIT, + POLL_THREAD_STATE_CLEAN, + POLL_THREAD_STATE_UPDATE, + POLL_THREAD_STATE_EXIT, + }; enum { ARC_STATE_REQUEST_ARC_INITIATION, - ARC_STATE_ARC_INITIATED, - ARC_STATE_REQUEST_ARC_TERMINATION, - ARC_STATE_ARC_TERMINATED, - ARC_STATE_ARC_EXIT - }; - enum { + ARC_STATE_ARC_INITIATED, + ARC_STATE_REQUEST_ARC_TERMINATION, + ARC_STATE_ARC_TERMINATED, + ARC_STATE_ARC_EXIT + }; + enum { VOLUME_UP = 0x41, - VOLUME_DOWN = 0x42, - MUTE = 0x43, - UP = 0x01, - DOWN = 0x02, - LEFT = 0x03, - RIGHT = 0x04, - SELECT = 0x00, - HOME = 0x09, - BACK = 0x0D, - NUMBER_0 = 0x20, - NUMBER_1 = 0x21, - NUMBER_2 = 0x22, - NUMBER_3 = 0x23, - NUMBER_4 = 0x24, - NUMBER_5 = 0x25, - NUMBER_6 = 0x26, - NUMBER_7 = 0x27, - NUMBER_8 = 0x28, - NUMBER_9 = 0x29 - }; + VOLUME_DOWN = 0x42, + MUTE = 0x43, + UP = 0x01, + DOWN = 0x02, + LEFT = 0x03, + RIGHT = 0x04, + SELECT = 0x00, + HOME = 0x09, + BACK = 0x0D, + NUMBER_0 = 0x20, + NUMBER_1 = 0x21, + NUMBER_2 = 0x22, + NUMBER_3 = 0x23, + NUMBER_4 = 0x24, + NUMBER_5 = 0x25, + NUMBER_6 = 0x26, + NUMBER_7 = 0x27, + NUMBER_8 = 0x28, + NUMBER_9 = 0x29 + }; public: HdmiCecSinkImplementation(); virtual ~HdmiCecSinkImplementation(); static HdmiCecSinkImplementation* _instance; - CECDeviceParams deviceList[16]; - std::vector hdmiInputs; - int m_currentActiveSource; - void updateInActiveSource(const int logical_address, const InActiveSource &source ); - void updateActiveSource(const int logical_address, const ActiveSource &source ); - void updateTextViewOn(const int logicalAddress); - void updateImageViewOn(const int logicalAddress); - void updateDeviceChain(const LogicalAddress &logicalAddress, const PhysicalAddress &phy_addr); - void getActiveRoute(const LogicalAddress &logicalAddress, std::vector &route); - void removeDevice(const int logicalAddress); - void addDevice(const int logicalAddress); - void printDeviceList(); - void setStreamPath( const PhysicalAddress &physical_addr); - void setRoutingChange(const std::string &from, const std::string &to); - void sendStandbyMessage(); - void setCurrentLanguage(const Language &lang); - void sendMenuLanguage(); - void setActiveSource(bool isResponse); - void requestActiveSource(); + CECDeviceParams deviceList[16]; + std::vector hdmiInputs; + int m_currentActiveSource; + void updateInActiveSource(const int logical_address, const InActiveSource &source ); + void updateActiveSource(const int logical_address, const ActiveSource &source ); + void updateTextViewOn(const int logicalAddress); + void updateImageViewOn(const int logicalAddress); + void updateDeviceChain(const LogicalAddress &logicalAddress, const PhysicalAddress &phy_addr); + void getActiveRoute(const LogicalAddress &logicalAddress, std::vector &route); + void removeDevice(const int logicalAddress); + void addDevice(const int logicalAddress); + void printDeviceList(); + void setStreamPath( const PhysicalAddress &physical_addr); + void setRoutingChange(const std::string &from, const std::string &to); + void sendStandbyMessage(); + void setCurrentLanguage(const Language &lang); + void sendMenuLanguage(); + void setActiveSource(bool isResponse); + void requestActiveSource(); void startArc(); void stopArc(); void Process_InitiateArc(); @@ -555,28 +555,28 @@ namespace WPEFramework { void updateArcState(); void requestShortaudioDescriptor(); void Send_ShortAudioDescriptor_Event(JsonArray audiodescriptor); - void Process_ShortAudioDescriptor_msg(const ReportShortAudioDescriptor &msg); - void Process_SetSystemAudioMode_msg(const SetSystemAudioMode &msg); - void sendDeviceUpdateInfo(const int logicalAddress); - void sendFeatureAbort(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason); - void reportFeatureAbortEvent(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason); - void systemAudioModeRequest(); + void Process_ShortAudioDescriptor_msg(const ReportShortAudioDescriptor &msg); + void Process_SetSystemAudioMode_msg(const SetSystemAudioMode &msg); + void sendDeviceUpdateInfo(const int logicalAddress); + void sendFeatureAbort(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason); + void reportFeatureAbortEvent(const LogicalAddress logicalAddress, const OpCode feature, const AbortReason reason); + void systemAudioModeRequest(); void SendStandbyMsgEvent(const int logicalAddress); void requestAudioDevicePowerStatus(); void reportAudioDevicePowerStatusInfo(const int logicalAddress, const int powerStatus); - void updateCurrentLatency(int videoLatency, bool lowLatencyMode, int audioOutputCompensated, int audioOutputDelay); - void setLatencyInfo(); + void updateCurrentLatency(int videoLatency, bool lowLatencyMode, int audioOutputCompensated, int audioOutputDelay); + void setLatencyInfo(); void Process_ReportAudioStatus_msg(const ReportAudioStatus msg); void sendKeyPressEvent(const int logicalAddress, int keyCode); void sendKeyReleaseEvent(const int logicalAddress); - void sendUserControlPressed(const int logicalAddress, int keyCode); + void sendUserControlPressed(const int logicalAddress, int keyCode); void sendUserControlReleased(const int logicalAddress); - void sendGiveAudioStatusMsg(); + void sendGiveAudioStatusMsg(); void onPowerModeChanged(const PowerState ¤tState, const PowerState &newState); void registerEventHandlers(); void getHdmiArcPortID(); - int m_numberOfDevices; /* Number of connected devices othethan own device */ - bool m_audioDevicePowerStatusRequested; + int m_numberOfDevices; /* Number of connected devices othethan own device */ + bool m_audioDevicePowerStatusRequested; BEGIN_INTERFACE_MAP(HdmiCecSinkImplementation) INTERFACE_ENTRY(Exchange::IHdmiCecSink) @@ -584,134 +584,133 @@ namespace WPEFramework { private: class PowerManagerNotification : public Exchange::IPowerManager::IModeChangedNotification { - private: - PowerManagerNotification(const PowerManagerNotification&) = delete; - PowerManagerNotification& operator=(const PowerManagerNotification&) = delete; - - public: - explicit PowerManagerNotification(HdmiCecSinkImplementation& parent) - : _parent(parent) - { - } - ~PowerManagerNotification() override = default; - - public: - void OnPowerModeChanged(const PowerState currentState, const PowerState newState) override - { - _parent.onPowerModeChanged(currentState, newState); - } - - template - T* baseInterface() - { - static_assert(std::is_base_of(), "base type mismatch"); - return static_cast(this); - } - - BEGIN_INTERFACE_MAP(PowerManagerNotification) - INTERFACE_ENTRY(Exchange::IPowerManager::IModeChangedNotification) - END_INTERFACE_MAP - - private: - HdmiCecSinkImplementation& _parent; - + private: + PowerManagerNotification(const PowerManagerNotification&) = delete; + PowerManagerNotification& operator=(const PowerManagerNotification&) = delete; + + public: + explicit PowerManagerNotification(HdmiCecSinkImplementation& parent) + : _parent(parent) + { + } + ~PowerManagerNotification() override = default; + + public: + void OnPowerModeChanged(const PowerState currentState, const PowerState newState) override + { + _parent.onPowerModeChanged(currentState, newState); + } + + template + T* baseInterface() + { + static_assert(std::is_base_of(), "base type mismatch"); + return static_cast(this); + } + + BEGIN_INTERFACE_MAP(PowerManagerNotification) + INTERFACE_ENTRY(Exchange::IPowerManager::IModeChangedNotification) + END_INTERFACE_MAP + + private: + HdmiCecSinkImplementation& _parent; + }; - // We do not allow this plugin to be copied !! - HdmiCecSinkImplementation(const HdmiCecSinkImplementation&) = delete; - HdmiCecSinkImplementation& operator=(const HdmiCecSinkImplementation&) = delete; - - //Begin methods - void InitializePowerManager(PluginHost::IShell *service); - //End methods - std::string logicalAddressDeviceType; - bool cecSettingEnabled; - bool cecOTPSettingEnabled; - bool cecEnableStatus; - bool hdmiCecAudioDeviceConnected; - bool m_isHdmiInConnected; - int m_numofHdmiInput; - uint8_t m_deviceType; - int m_logicalAddressAllocated; - std::thread m_pollThread; - uint32_t m_pollThreadState; - uint32_t m_pollNextState; - bool m_pollThreadExit; - uint32_t m_sleepTime; - std::mutex m_pollExitMutex; - std::mutex m_enableMutex; - /* Send Key event related */ - bool m_sendKeyEventThreadExit; - bool m_sendKeyEventThreadRun; - bool m_isAudioStatusInfoUpdated; - bool m_audioStatusReceived; - bool m_audioStatusTimerStarted; - std::thread m_sendKeyEventThread; - std::mutex m_sendKeyEventMutex; - std::queue m_SendKeyQueue; - std::condition_variable m_sendKeyCV; - std::condition_variable m_ThreadExitCV; + // We do not allow this plugin to be copied !! + HdmiCecSinkImplementation(const HdmiCecSinkImplementation&) = delete; + HdmiCecSinkImplementation& operator=(const HdmiCecSinkImplementation&) = delete; + //Begin methods + void InitializePowerManager(PluginHost::IShell *service); + //End methods + std::string logicalAddressDeviceType; + bool cecSettingEnabled; + bool cecOTPSettingEnabled; + bool cecEnableStatus; + bool hdmiCecAudioDeviceConnected; + bool m_isHdmiInConnected; + int m_numofHdmiInput; + uint8_t m_deviceType; + int m_logicalAddressAllocated; + std::thread m_pollThread; + uint32_t m_pollThreadState; + uint32_t m_pollNextState; + bool m_pollThreadExit; + uint32_t m_sleepTime; + std::mutex m_pollExitMutex; + std::mutex m_enableMutex; + /* Send Key event related */ + bool m_sendKeyEventThreadExit; + bool m_sendKeyEventThreadRun; + bool m_isAudioStatusInfoUpdated; + bool m_audioStatusReceived; + bool m_audioStatusTimerStarted; + std::thread m_sendKeyEventThread; + std::mutex m_sendKeyEventMutex; + std::queue m_SendKeyQueue; + std::condition_variable m_sendKeyCV; + std::condition_variable m_ThreadExitCV; /* DALS - Latency Values */ - uint8_t m_video_latency; - uint8_t m_latency_flags; - uint8_t m_audio_output_delay; + uint8_t m_video_latency; + uint8_t m_latency_flags; + uint8_t m_audio_output_delay; - /* ARC related */ + /* ARC related */ std::thread m_arcRoutingThread; - uint32_t m_currentArcRoutingState; - std::mutex m_arcRoutingStateMutex; - binary_semaphore m_semSignaltoArcRoutingThread; - bool m_arcstarting; - TpTimer m_arcStartStopTimer; - TpTimer m_audioStatusDetectionTimer; - - Connection *smConnection; - std::vector m_connectedDevices; - HdmiCecSinkProcessor *msgProcessor; - HdmiCecSinkFrameListener *msgFrameListener; - PowerManagerInterfaceRef _powerManagerPlugin; - Core::Sink _pwrMgrNotification; - bool _registeredEventHandlers; - const void InitializeIARM(); - void DeinitializeIARM(); - void allocateLogicalAddress(int deviceType); - void allocateLAforTV(); - void pingDevices(std::vector &connected , std::vector &disconnected); - void CheckHdmiInState(); - void request(const int logicalAddress); - int requestType(const int logicalAddress); - int requestStatus(const int logicalAddress); - static void threadRun(); - void cecMonitoringThread(); - static void dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); - void onHdmiHotPlug(int portId, int connectStatus); - bool loadSettings(); - void persistSettings(bool enableStatus); - void persistOTPSettings(bool enableStatus); - void persistOSDName(const char *name); - void persistVendorId(unsigned int vendorID); - void setEnabled(bool enabled); - bool getEnabled(); - bool getAudioDeviceConnectedStatus(); - void CECEnable(void); - void CECDisable(void); - void getPhysicalAddress(); - void getLogicalAddress(); - void cecAddressesChanged(int changeStatus); + uint32_t m_currentArcRoutingState; + std::mutex m_arcRoutingStateMutex; + binary_semaphore m_semSignaltoArcRoutingThread; + bool m_arcstarting; + TpTimer m_arcStartStopTimer; + TpTimer m_audioStatusDetectionTimer; + + Connection *smConnection; + std::vector m_connectedDevices; + HdmiCecSinkProcessor *msgProcessor; + HdmiCecSinkFrameListener *msgFrameListener; + PowerManagerInterfaceRef _powerManagerPlugin; + Core::Sink _pwrMgrNotification; + bool _registeredEventHandlers; + const void InitializeIARM(); + void DeinitializeIARM(); + void allocateLogicalAddress(int deviceType); + void allocateLAforTV(); + void pingDevices(std::vector &connected , std::vector &disconnected); + void CheckHdmiInState(); + void request(const int logicalAddress); + int requestType(const int logicalAddress); + int requestStatus(const int logicalAddress); + static void threadRun(); + void cecMonitoringThread(); + static void dsHdmiEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len); + void onHdmiHotPlug(int portId, int connectStatus); + bool loadSettings(); + void persistSettings(bool enableStatus); + void persistOTPSettings(bool enableStatus); + void persistOSDName(const char *name); + void persistVendorId(unsigned int vendorID); + void setEnabled(bool enabled); + bool getEnabled(); + bool getAudioDeviceConnectedStatus(); + void CECEnable(void); + void CECDisable(void); + void getPhysicalAddress(); + void getLogicalAddress(); + void cecAddressesChanged(int changeStatus); - // Arc functions - - static void threadSendKeyEvent(); - static void threadArcRouting(); - void requestArcInitiation(); - void requestArcTermination(); - void Send_Request_Arc_Initiation_Message(); - void Send_Report_Arc_Initiated_Message(); - void Send_Request_Arc_Termination_Message(); - void Send_Report_Arc_Terminated_Message(); - void arcStartStopTimerFunction(); - void audioStatusTimerFunction(); - void getCecVersion(); + // Arc functions + + static void threadSendKeyEvent(); + static void threadArcRouting(); + void requestArcInitiation(); + void requestArcTermination(); + void Send_Request_Arc_Initiation_Message(); + void Send_Report_Arc_Initiated_Message(); + void Send_Request_Arc_Termination_Message(); + void Send_Report_Arc_Terminated_Message(); + void arcStartStopTimerFunction(); + void audioStatusTimerFunction(); + void getCecVersion(); public: @@ -739,15 +738,16 @@ namespace WPEFramework { Core::hresult SetupARCRouting(const bool &enabled, HdmiCecSinkSuccess &success) override; Core::hresult SetVendorId(const string &vendorId, HdmiCecSinkSuccess &success) override; Core::hresult SetLatencyInfo(const string &videoLatency, const string &lowLatencyMode, const string &audioOutputCompensated, const string &audioOutputDelay, HdmiCecSinkSuccess &success) override; - Core::hresult Configure(PluginHost::IShell* service) override; + Core::hresult Configure(PluginHost::IShell* service) override; Core::hresult Register(Exchange::IHdmiCecSink::INotification *notification) override; Core::hresult Unregister(Exchange::IHdmiCecSink::INotification *notification) override; + Core::hresult setMenuLanguage(const string &language, HdmiCecSinkSuccess &success) override; private: std::list _hdmiCecSinkNotifications; - mutable Core::CriticalSection _adminLock; + mutable Core::CriticalSection _adminLock; }; - } // namespace Plugin + } // namespace Plugin } // namespace WPEFramework From ccba11b18bf4f4278c29380e3c22f31dfcb3efe3 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:47:06 -0400 Subject: [PATCH 44/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 334f96c4..a4adbbfb 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -1603,7 +1603,7 @@ namespace WPEFramework return Core::ERROR_NONE; } - Core::hresult HdmiCecSink::setMenuLanguage(const string &language, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::setMenuLanguage(const string &language, HdmiCecSinkSuccess &success) { std::string lang; From 15913a1b199146c447639f5d4830e783a4b33e6d Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:55:17 -0400 Subject: [PATCH 45/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 4 ++-- HdmiCecSink/HdmiCecSinkImplementation.h | 4 ++-- HdmiCecSource/HdmiCecSourceImplementation.cpp | 2 +- HdmiCecSource/HdmiCecSourceImplementation.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index a4adbbfb..5e6e0e62 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -229,7 +229,7 @@ namespace WPEFramework if(!updateStatus) HdmiCecSinkImplementation::_instance->sendDeviceUpdateInfo(header.from.toInt()); } - void HdmiCecSinkProcessor::process (const SetMenuLanguage &msg, const Header &header) + void HdmiCecSinkProcessor::process (const SetMenuLanguageMessage &msg, const Header &header) { printHeader(header); LOGINFO("Command: SetMenuLanguage Language : %s \n",msg.language.toString().c_str()); @@ -1603,7 +1603,7 @@ namespace WPEFramework return Core::ERROR_NONE; } - Core::hresult HdmiCecSinkImplementation::setMenuLanguage(const string &language, HdmiCecSinkSuccess &success) + Core::hresult HdmiCecSinkImplementation::SetMenuLanguage(const string &language, HdmiCecSinkSuccess &success) { std::string lang; diff --git a/HdmiCecSink/HdmiCecSinkImplementation.h b/HdmiCecSink/HdmiCecSinkImplementation.h index 77bb940f..c9d91c11 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.h +++ b/HdmiCecSink/HdmiCecSinkImplementation.h @@ -73,7 +73,7 @@ namespace WPEFramework { void process (const Standby &msg, const Header &header); void process (const GetCECVersion &msg, const Header &header); void process (const CECVersion &msg, const Header &header); - void process (const SetMenuLanguage &msg, const Header &header); + void process (const SetMenuLanguageMessage &msg, const Header &header); void process (const GiveOSDName &msg, const Header &header); void process (const GivePhysicalAddress &msg, const Header &header); void process (const GiveDeviceVendorID &msg, const Header &header); @@ -741,7 +741,7 @@ namespace WPEFramework { Core::hresult Configure(PluginHost::IShell* service) override; Core::hresult Register(Exchange::IHdmiCecSink::INotification *notification) override; Core::hresult Unregister(Exchange::IHdmiCecSink::INotification *notification) override; - Core::hresult setMenuLanguage(const string &language, HdmiCecSinkSuccess &success) override; + Core::hresult SetMenuLanguage(const string &language, HdmiCecSinkSuccess &success) override; private: std::list _hdmiCecSinkNotifications; diff --git a/HdmiCecSource/HdmiCecSourceImplementation.cpp b/HdmiCecSource/HdmiCecSourceImplementation.cpp index 50809956..1086f6ac 100644 --- a/HdmiCecSource/HdmiCecSourceImplementation.cpp +++ b/HdmiCecSource/HdmiCecSourceImplementation.cpp @@ -178,7 +178,7 @@ namespace WPEFramework LOGINFO("Command: CECVersion Version : %s \n",msg.version.toString().c_str()); HdmiCecSourceImplementation::_instance->addDevice(header.from.toInt()); } - void HdmiCecSourceProcessor::process (const SetMenuLanguage &msg, const Header &header) + void HdmiCecSourceProcessor::process (const SetMenuLanguageMessage &msg, const Header &header) { printHeader(header); LOGINFO("Command: SetMenuLanguage Language : %s \n",msg.language.toString().c_str()); diff --git a/HdmiCecSource/HdmiCecSourceImplementation.h b/HdmiCecSource/HdmiCecSourceImplementation.h index a5936907..d0494a18 100644 --- a/HdmiCecSource/HdmiCecSourceImplementation.h +++ b/HdmiCecSource/HdmiCecSourceImplementation.h @@ -72,7 +72,7 @@ namespace WPEFramework { void process (const Standby &msg, const Header &header); void process (const GetCECVersion &msg, const Header &header); void process (const CECVersion &msg, const Header &header); - void process (const SetMenuLanguage &msg, const Header &header); + void process (const SetMenuLanguageMessage &msg, const Header &header); void process (const GiveOSDName &msg, const Header &header); void process (const GivePhysicalAddress &msg, const Header &header); void process (const GiveDeviceVendorID &msg, const Header &header); From e705dfe9f5178945c8be72fc98a8e88f2aa21ae9 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Tue, 3 Jun 2025 10:07:05 -0400 Subject: [PATCH 46/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSinkImplementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HdmiCecSink/HdmiCecSinkImplementation.cpp b/HdmiCecSink/HdmiCecSinkImplementation.cpp index 5e6e0e62..7363bb76 100644 --- a/HdmiCecSink/HdmiCecSinkImplementation.cpp +++ b/HdmiCecSink/HdmiCecSinkImplementation.cpp @@ -2102,7 +2102,7 @@ namespace WPEFramework lang = _instance->deviceList[_instance->m_logicalAddressAllocated].m_currentLanguage; - _instance->smConnection->sendTo(LogicalAddress::BROADCAST, MessageEncoder().encode(SetMenuLanguage(lang)), 100); + _instance->smConnection->sendTo(LogicalAddress::BROADCAST, MessageEncoder().encode(SetMenuLanguageMessage(lang)), 100); } void HdmiCecSinkImplementation::updateInActiveSource(const int logical_address, const InActiveSource &source ) From a3fd3afaf85c91755cffbca0787c1a83c3368d0a Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Thu, 5 Jun 2025 09:42:21 -0400 Subject: [PATCH 47/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- HdmiCecSink/HdmiCecSink.conf.in | 7 +++++++ HdmiCecSink/HdmiCecSink.config | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/HdmiCecSink/HdmiCecSink.conf.in b/HdmiCecSink/HdmiCecSink.conf.in index de8e1cdf..646c4430 100644 --- a/HdmiCecSink/HdmiCecSink.conf.in +++ b/HdmiCecSink/HdmiCecSink.conf.in @@ -2,3 +2,10 @@ precondition = ["Platform"] callsign = "org.rdk.HdmiCecSink" autostart = "false" startuporder = "@PLUGIN_HDMICECSINK_STARTUPORDER@" + +configuration = JSON() +rootobject = JSON() + +rootobject.add("mode", "@PLUGIN_HDMICECSINK_MODE@") +rootobject.add("locator", "lib@PLUGIN_IMPLEMENTATION@.so") +configuration.add("root", rootobject) \ No newline at end of file diff --git a/HdmiCecSink/HdmiCecSink.config b/HdmiCecSink/HdmiCecSink.config index 13ed0788..7257c9e8 100644 --- a/HdmiCecSink/HdmiCecSink.config +++ b/HdmiCecSink/HdmiCecSink.config @@ -5,3 +5,13 @@ set (callsign "org.rdk.HdmiCecSink") if(PLUGIN_HDMICECSINK_STARTUPORDER) set (startuporder ${PLUGIN_HDMICECSINK_STARTUPORDER}) endif() + + +map() + key(root) + map() + kv(mode ${PLUGIN_HDMICECSOURCE_MODE}) + kv(locator lib${PLUGIN_IMPLEMENTATION}.so) + end() +end() +ans(configuration) From 0be9df32ae3ce6bba2bdf290ab898bc9010c4c56 Mon Sep 17 00:00:00 2001 From: hgfell683 <107510770+hgfell683@users.noreply.github.com> Date: Fri, 20 Jun 2025 10:54:03 -0400 Subject: [PATCH 48/48] RDKEMW-1015 : HDMICEC SINK COMRPC --- .github/workflows/L1-tests.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index 9366eaa5..d5748acf 100755 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -435,8 +435,8 @@ jobs: -DPLUGIN_AVINPUT=ON -DPLUGIN_HDMIINPUT=ON -DPLUGIN_HDCPPROFILE=ON - -DPLUGIN_HDMICECSOURCE=ON - -DPLUGIN_HDMICECSINK=ON + -DPLUGIN_HDMICECSOURCE=OFF + -DPLUGIN_HDMICECSINK=OFF -DUSE_THUNDER_R4=ON -DHIDE_NON_EXTERNAL_SYMBOLS=OFF && @@ -513,8 +513,8 @@ jobs: -DPLUGIN_AVINPUT=ON -DPLUGIN_HDMIINPUT=ON -DPLUGIN_HDCPPROFILE=ON - -DPLUGIN_HDMICECSOURCE=ON - -DPLUGIN_HDMICECSINK=ON + -DPLUGIN_HDMICECSOURCE=OFF + -DPLUGIN_HDMICECSINK=OFF -DRDK_SERVICES_L1_TEST=ON -DUSE_THUNDER_R4=ON -DHIDE_NON_EXTERNAL_SYMBOLS=OFF