X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fadapter%2FUSBCECAdapterCommunication.h;h=7409e86d874b002b356a16a39cdea1b3931f2e70;hb=c0152c0940ee81c79150dbafafd6621f576c3ccb;hp=659e65922d1a519fb946ffda8a7817d071f68e71;hpb=224ea8772f229d2d7dafcdbf64c4266c9b4de35e;p=deb_libcec.git diff --git a/src/lib/adapter/USBCECAdapterCommunication.h b/src/lib/adapter/USBCECAdapterCommunication.h index 659e659..7409e86 100644 --- a/src/lib/adapter/USBCECAdapterCommunication.h +++ b/src/lib/adapter/USBCECAdapterCommunication.h @@ -45,54 +45,141 @@ namespace PLATFORM namespace CEC { class CCECProcessor; + class CAdapterPingThread; + class CUSBCECAdapterCommands; + class CCECAdapterMessageQueue; - class CUSBCECAdapterCommunication : public IAdapterCommunication, private PLATFORM::CThread + class CUSBCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread { - public: - CUSBCECAdapterCommunication(CCECProcessor *processor, const char *strPort, uint16_t iBaudRate = 38400); - virtual ~CUSBCECAdapterCommunication(); + friend class CUSBCECAdapterCommands; + friend class CCECAdapterMessageQueue; - virtual bool Open(IAdapterCommunicationCallback *cb, uint32_t iTimeoutMs = 10000); - virtual void Close(void); - virtual bool IsOpen(void); - virtual CStdString GetError(void) const; + public: + /*! + * @brief Create a new USB-CEC communication handler. + * @param callback The callback to use for incoming CEC commands. + * @param strPort The name of the com port to use. + * @param iBaudRate The baudrate to use on the com port connection. + */ + CUSBCECAdapterCommunication(IAdapterCommunicationCallback *callback, const char *strPort, uint16_t iBaudRate = CEC_SERIAL_DEFAULT_BAUDRATE); + virtual ~CUSBCECAdapterCommunication(void); - bool Read(cec_command &command, uint32_t iTimeout); - cec_adapter_message_state Write(const cec_command &data, uint8_t iMaxTries, uint8_t iLineTimeout = 3, uint8_t iRetryLineTimeout = 3); + /** @name IAdapterCommunication implementation */ + ///{ + bool Open(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT, bool bSkipChecks = false, bool bStartListening = true); + void Close(void); + bool IsOpen(void); + CStdString GetError(void) const; + cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout = 3); - virtual bool SetLineTimeout(uint8_t iTimeout); - virtual bool StartBootloader(void); - virtual bool SetAckMask(uint16_t iMask); - virtual bool PingAdapter(void); - virtual uint16_t GetFirmwareVersion(void); - virtual bool SetControlledMode(bool controlled); - virtual bool PersistConfiguration(libcec_configuration * UNUSED(configuration)) { return false; } // TODO + bool StartBootloader(void); + bool SetAckMask(uint16_t iMask); + uint16_t GetAckMask(void); + bool PingAdapter(void); + uint16_t GetFirmwareVersion(void); + uint32_t GetFirmwareBuildDate(void); + bool IsRunningLatestFirmware(void); + bool PersistConfiguration(const libcec_configuration &configuration); + bool GetConfiguration(libcec_configuration &configuration); + CStdString GetPortName(void); + uint16_t GetPhysicalAddress(void) { return 0; } + bool SetControlledMode(bool controlled); + ///} void *Process(void); + private: - bool CheckAdapter(uint32_t iTimeoutMs = 10000); - bool Write(CCECAdapterMessage *data); - bool Read(CCECAdapterMessage &msg, uint32_t iTimeout = 1000); - bool ParseMessage(const CCECAdapterMessage &msg); - void SendMessageToAdapter(CCECAdapterMessage *msg); - void WriteNextCommand(void); - void AddData(uint8_t *data, size_t iLen); + /*! + * @brief Clear all input bytes. + * @param iTimeout Timeout when anything was received. + */ + void ClearInputBytes(uint32_t iTimeout = CEC_CLEAR_INPUT_DEFAULT_WAIT); + + /*! + * @brief Change the current CEC line timeout. + * @param iTimeout The new timeout. + * @return True when acked by the controller, false otherwise. + */ + bool SetLineTimeout(uint8_t iTimeout); + + /*! + * @brief Send a command to the controller and wait for an ack. + * @param msgCode The command to send. + * @param params The parameters to the command. + * @param bIsRetry True when this command is being retried, false otherwise. + * @return The message. Delete when done with it. + */ + CCECAdapterMessage *SendCommand(cec_adapter_messagecode msgCode, CCECAdapterMessage ¶ms, bool bIsRetry = false); + + /*! + * @brief Change the "initialised" status. + * @param bSetTo The new value. + */ + void SetInitialised(bool bSetTo = true); + + /*! + * @return True when initialised, false otherwise. + */ + bool IsInitialised(void); + + /*! + * @brief Pings the adapter, checks the firmware version and sets controlled mode. + * @param iTimeoutMs The timeout after which this fails if no proper data was received. + * @return True when the checks passed, false otherwise. + */ + bool CheckAdapter(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT); + + /*! + * @brief Handle a poll message inside the adapter message (checks if one is present). + * @param msg The adapter message to parse. + * @return True when the message resulted in a CEC error, false otherwise. + */ + bool HandlePoll(const CCECAdapterMessage &msg); + + /*! + * @brief Read data from the device. + * @param iTimeout The read timeout to use. + * @param iSize The maximum read size. + * @return True when something was read, false otherwise. + */ bool ReadFromDevice(uint32_t iTimeout, size_t iSize = 256); - bool WaitForAck(CCECAdapterMessage &message); - - PLATFORM::ISocket * m_port; - CCECProcessor * m_processor; - PLATFORM::SyncedBuffer m_inBuffer; - PLATFORM::SyncedBuffer m_outBuffer; - PLATFORM::CMutex m_mutex; - PLATFORM::CCondition m_rcvCondition; - uint8_t m_iLineTimeout; - uint16_t m_iFirmwareVersion; - cec_command m_currentframe; - cec_logical_address m_lastInitiator; - CCECAdapterMessage m_currentAdapterMessage; - bool m_bNextIsEscaped; - bool m_bGotStart; - IAdapterCommunicationCallback * m_callback; + + /*! + * @brief Writes a message to the serial port. + * @param message The message to write. + * @return True when written, false otherwise. + */ + bool WriteToDevice(CCECAdapterMessage *message); + + /*! + * @brief Called before sending a CEC command over the line, so we know we're expecting an ack. + * @param dest The destination of the CEC command. + */ + void MarkAsWaiting(const cec_logical_address dest); + + PLATFORM::ISocket * m_port; /**< the com port connection */ + PLATFORM::CMutex m_mutex; /**< mutex for changes in this class */ + uint8_t m_iLineTimeout; /**< the current line timeout on the CEC line */ + cec_logical_address m_lastPollDestination; /**< the destination of the last poll message that was received */ + bool m_bInitialised; /**< true when the connection is initialised, false otherwise */ + bool m_bWaitingForAck[15]; /**< array in which we store from which devices we're expecting acks */ + CAdapterPingThread * m_pingThread; /**< ping thread, that pings the adapter every 15 seconds */ + CUSBCECAdapterCommands * m_commands; /**< commands that can be sent to the adapter */ + CCECAdapterMessageQueue * m_adapterMessageQueue; /**< the incoming and outgoing message queue */ + uint16_t m_iAckMask; + }; + + class CAdapterPingThread : public PLATFORM::CThread + { + public: + CAdapterPingThread(CUSBCECAdapterCommunication *com, uint32_t iTimeout) : + m_com(com), + m_timeout(iTimeout){} + virtual ~CAdapterPingThread(void) {} + + virtual void* Process(void); + private: + CUSBCECAdapterCommunication *m_com; + PLATFORM::CTimeout m_timeout; }; };