1 #pragma once 2 /* 3 * This file is part of the libCEC(R) library. 4 * 5 * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited. All rights reserved. 6 * libCEC(R) is an original work, containing original code. 7 * 8 * libCEC(R) is a trademark of Pulse-Eight Limited. 9 * 10 * This program is dual-licensed; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 23 * 02110-1301 USA 24 * 25 * 26 * Alternatively, you can license this library under a commercial license, 27 * please contact Pulse-Eight Licensing for more information. 28 * 29 * For more information contact: 30 * Pulse-Eight Licensing <license@pulse-eight.com> 31 * http://www.pulse-eight.com/ 32 * http://www.pulse-eight.net/ 33 */ 34 35 #include "env.h" 36 #include <string> 37 #include "p8-platform/threads/threads.h" 38 #include "p8-platform/util/buffer.h" 39 #include "adapter/AdapterCommunication.h" 40 #include "devices/CECDeviceMap.h" 41 #include "CECInputBuffer.h" 42 #include <memory> 43 44 namespace CEC 45 { 46 class CLibCEC; 47 class IAdapterCommunication; 48 class CCECBusDevice; 49 class CCECAudioSystem; 50 class CCECPlaybackDevice; 51 class CCECRecordingDevice; 52 class CCECTuner; 53 class CCECTV; 54 class CCECClient; 55 class CCECProcessor; 56 class CCECStandbyProtection; 57 typedef std::shared_ptr<CCECClient> CECClientPtr; 58 59 typedef struct 60 { 61 CECClientPtr client; 62 cec_device_type from; 63 cec_device_type to; 64 } device_type_change_t; 65 66 class CCECAllocateLogicalAddress : public P8PLATFORM::CThread 67 { 68 public: 69 CCECAllocateLogicalAddress(CCECProcessor* processor, CECClientPtr client); 70 void* Process(void); 71 72 private: 73 CCECProcessor* m_processor; 74 CECClientPtr m_client; 75 }; 76 77 class CCECProcessor : public P8PLATFORM::CThread, public IAdapterCommunicationCallback 78 { 79 public: 80 CCECProcessor(CLibCEC *libcec); 81 virtual ~CCECProcessor(void); 82 83 bool Start(const char *strPort, uint16_t iBaudRate = CEC_SERIAL_DEFAULT_BAUDRATE, uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT); 84 void *Process(void); 85 void Close(void); 86 87 bool RegisterClient(CCECClient* client); 88 bool RegisterClient(CECClientPtr client); 89 bool UnregisterClient(CCECClient* client); 90 bool UnregisterClient(CECClientPtr client); 91 void UnregisterClients(void); 92 uint16_t GetPhysicalAddressFromEeprom(void); 93 CECClientPtr GetPrimaryClient(void); 94 CECClientPtr GetClient(const cec_logical_address address); 95 96 bool OnCommandReceived(const cec_command &command); 97 void HandleLogicalAddressLost(cec_logical_address oldAddress); 98 void HandlePhysicalAddressChanged(uint16_t iNewAddress); 99 100 CCECBusDevice * GetDevice(cec_logical_address address) const; 101 CCECAudioSystem * GetAudioSystem(void) const; 102 CCECPlaybackDevice * GetPlaybackDevice(cec_logical_address address) const; 103 CCECRecordingDevice * GetRecordingDevice(cec_logical_address address) const; 104 CCECTuner * GetTuner(cec_logical_address address) const; 105 CCECTV * GetTV(void) const; 106 107 CCECBusDevice * GetDeviceByPhysicalAddress(uint16_t iPhysicalAddress, bool bSuppressUpdate = true); 108 CCECBusDevice * GetPrimaryDevice(void); 109 cec_logical_address GetLogicalAddress(void); 110 cec_logical_addresses GetLogicalAddresses(void); 111 bool IsPresentDevice(cec_logical_address address); 112 bool IsPresentDeviceType(cec_device_type type); 113 uint16_t GetDetectedPhysicalAddress(void) const; GetLastTransmission(void)114 uint64_t GetLastTransmission(void) const { return m_iLastTransmission; } 115 cec_logical_address GetActiveSource(bool bRequestActiveSource = true); 116 bool IsActiveSource(cec_logical_address iAddress); 117 bool CECInitialised(void); 118 119 bool StandbyDevices(const cec_logical_address initiator, const CECDEVICEVEC &devices); 120 bool StandbyDevice(const cec_logical_address initiator, cec_logical_address address); 121 bool PowerOnDevices(const cec_logical_address initiator, const CECDEVICEVEC &devices); 122 bool PowerOnDevice(const cec_logical_address initiator, cec_logical_address address); 123 124 void ChangeDeviceType(CECClientPtr client, cec_device_type from, cec_device_type to); 125 bool SetDeckInfo(cec_deck_info info, bool bSendUpdate = true); 126 bool ActivateSource(uint16_t iStreamPath); 127 void SetActiveSource(bool bSetTo, bool bClientUnregistered); 128 bool GetStats(struct cec_adapter_stats* stats); 129 bool PollDevice(cec_logical_address iAddress); 130 void SetStandardLineTimeout(uint8_t iTimeout); 131 uint8_t GetStandardLineTimeout(void); 132 void SetRetryLineTimeout(uint8_t iTimeout); 133 uint8_t GetRetryLineTimeout(void); 134 bool CanSaveConfiguration(void); 135 bool SaveConfiguration(const libcec_configuration &configuration); 136 bool SetAutoMode(bool automode); 137 void RescanActiveDevices(void); 138 139 bool SetLineTimeout(uint8_t iTimeout); 140 141 bool Transmit(const cec_command &data, bool bIsReply); 142 void TransmitAbort(cec_logical_address source, cec_logical_address destination, cec_opcode opcode, cec_abort_reason reason = CEC_ABORT_REASON_UNRECOGNIZED_OPCODE); 143 144 bool StartBootloader(const char *strPort = NULL); 145 bool PingAdapter(void); 146 void HandlePoll(cec_logical_address initiator, cec_logical_address destination); 147 bool HandleReceiveFailed(cec_logical_address initiator); 148 149 bool GetDeviceInformation(const char *strPort, libcec_configuration *config, uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT); 150 151 bool TransmitPendingActiveSourceCommands(void); 152 GetDevices(void)153 CCECDeviceMap *GetDevices(void) const { return m_busDevices; } GetLib(void)154 CLibCEC *GetLib(void) const { return m_libcec; } 155 156 bool IsHandledByLibCEC(const cec_logical_address address) const; 157 158 bool TryLogicalAddress(cec_logical_address address, cec_version libCECSpecVersion = CEC_VERSION_1_4); 159 160 bool IsRunningLatestFirmware(void); 161 void SwitchMonitoring(bool bSwitchTo); 162 163 bool AllocateLogicalAddresses(CECClientPtr client); 164 165 uint16_t GetAdapterVendorId(void) const; 166 uint16_t GetAdapterProductId(void) const; 167 private: 168 bool OpenConnection(const char *strPort, uint16_t iBaudRate, uint32_t iTimeoutMs, bool bStartListening = true); 169 void SetCECInitialised(bool bSetTo = true); 170 171 void ReplaceHandlers(void); 172 bool PhysicalAddressInUse(uint16_t iPhysicalAddress); 173 174 bool ClearLogicalAddresses(void); 175 bool SetLogicalAddresses(const cec_logical_addresses &addresses); 176 177 void LogOutput(const cec_command &data); 178 void ProcessCommand(const cec_command &command); 179 180 void ResetMembers(void); 181 182 bool m_bInitialised; 183 P8PLATFORM::CMutex m_mutex; 184 IAdapterCommunication * m_communication; 185 CLibCEC* m_libcec; 186 uint8_t m_iStandardLineTimeout; 187 uint8_t m_iRetryLineTimeout; 188 uint64_t m_iLastTransmission; 189 CCECInputBuffer m_inBuffer; 190 CCECDeviceMap * m_busDevices; 191 std::map<cec_logical_address, CECClientPtr> m_clients; 192 bool m_bMonitor; 193 CCECAllocateLogicalAddress* m_addrAllocator; 194 bool m_bStallCommunication; 195 CCECStandbyProtection* m_connCheck; 196 std::vector<device_type_change_t> m_deviceTypeChanges; 197 }; 198 199 class CCECStandbyProtection : public P8PLATFORM::CThread 200 { 201 public: 202 CCECStandbyProtection(CCECProcessor* processor); 203 virtual ~CCECStandbyProtection(void); 204 void* Process(void); 205 206 private: 207 CCECProcessor* m_processor; 208 }; 209 }; 210