cec: moved cec_adapter_message to CCECAdapterMessage
[deb_libcec.git] / src / lib / AdapterCommunication.h
index 32d4a157ebb7bf77a7eca084c91653cf46d0175b..c9a8e8c1155de1132d85c324c702182b5123e538 100644 (file)
 
 namespace CEC
 {
+  class CCECAdapterMessage
+  {
+  public:
+    CCECAdapterMessage(void) {}
+    CCECAdapterMessage(const cec_command &command)
+    {
+      clear();
+
+      //set ack polarity to high when transmitting to the broadcast address
+      //set ack polarity low when transmitting to any other address
+      push_back(MSGSTART);
+      push_escaped(MSGCODE_TRANSMIT_ACK_POLARITY);
+      if (command.destination == CECDEVICE_BROADCAST)
+        push_escaped(CEC_TRUE);
+      else
+        push_escaped(CEC_FALSE);
+      push_back(MSGEND);
+
+      // add source and destination
+      push_back(MSGSTART);
+      push_escaped(MSGCODE_TRANSMIT);
+      push_back(((uint8_t)command.initiator << 4) + (uint8_t)command.destination);
+      push_back(MSGEND);
+
+      // add opcode
+      push_back(MSGSTART);
+      push_escaped(command.parameters.empty() ? (uint8_t)MSGCODE_TRANSMIT_EOM : (uint8_t)MSGCODE_TRANSMIT);
+      push_back((uint8_t) command.opcode);
+      push_back(MSGEND);
+
+      // add parameters
+      for (int8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
+      {
+        push_back(MSGSTART);
+
+        if (iPtr == command.parameters.size - 1)
+          push_escaped( MSGCODE_TRANSMIT_EOM);
+        else
+          push_escaped(MSGCODE_TRANSMIT);
+
+        push_escaped(command.parameters[iPtr]);
+
+        push_back(MSGEND);
+      }
+    }
+
+    CCECAdapterMessage &operator =(const CCECAdapterMessage &msg)
+    {
+      packet = msg.packet;
+      return *this;
+    }
+
+    bool                    empty(void) const             { return packet.empty(); }
+    uint8_t                 operator[](uint8_t pos) const { return packet[pos]; }
+    uint8_t                 at(uint8_t pos) const         { return packet[pos]; }
+    uint8_t                 size(void) const              { return packet.size; }
+    void                    clear(void)                   { packet.clear(); }
+    void                    shift(uint8_t iShiftBy)       { packet.shift(iShiftBy); }
+    void                    push_back(uint8_t add)        { packet.push_back(add); }
+    cec_adapter_messagecode message(void) const           { return packet.size >= 1 ? (cec_adapter_messagecode) (packet.at(0) & ~(MSGCODE_FRAME_EOM | MSGCODE_FRAME_ACK))  : MSGCODE_NOTHING; }
+    bool                    eom(void) const               { return packet.size >= 1 ? (packet.at(0) & MSGCODE_FRAME_EOM) != 0 : false; }
+    bool                    ack(void) const               { return packet.size >= 1 ? (packet.at(0) & MSGCODE_FRAME_ACK) != 0 : false; }
+    cec_logical_address     initiator(void) const         { return packet.size >= 2 ? (cec_logical_address) (packet.at(1) >> 4)  : CECDEVICE_UNKNOWN; };
+    cec_logical_address     destination(void) const       { return packet.size >= 2 ? (cec_logical_address) (packet.at(1) & 0xF) : CECDEVICE_UNKNOWN; };
+    void                    push_escaped(int16_t byte)
+    {
+      if (byte >= MSGESC && byte != MSGSTART)
+      {
+        push_back(MSGESC);
+        push_back(byte - ESCOFFSET);
+      }
+      else
+         push_back(byte);
+    }
+
+    cec_datapacket packet;
+  };
+
   class CSerialPort;
   class CLibCEC;
 
@@ -48,8 +126,8 @@ namespace CEC
     virtual ~CAdapterCommunication();
 
     bool Open(const char *strPort, uint16_t iBaudRate = 38400, uint32_t iTimeoutMs = 10000);
-    bool Read(cec_adapter_message &msg, uint32_t iTimeout = 1000);
-    bool Write(const cec_adapter_message &frame);
+    bool Read(CCECAdapterMessage &msg, uint32_t iTimeout = 1000);
+    bool Write(const CCECAdapterMessage &frame);
     bool PingAdapter(void);
     void Close(void);
     bool IsOpen(void) const;
@@ -59,20 +137,18 @@ namespace CEC
 
     bool StartBootloader(void);
     bool SetAckMask(uint16_t iMask);
-    static void PushEscaped(cec_adapter_message &vec, uint8_t byte);
-    static void FormatAdapterMessage(const cec_command &command, cec_adapter_message &packet);
 
   private:
     void WriteNextCommand(void);
     void AddData(uint8_t *data, uint8_t iLen);
     bool ReadFromDevice(uint32_t iTimeout);
 
-    CSerialPort *                  m_port;
-    CLibCEC *                      m_controller;
-    CecBuffer<uint8_t>             m_inBuffer;
-    CecBuffer<cec_adapter_message> m_outBuffer;
-    CMutex                         m_bufferMutex;
-    CMutex                         m_commMutex;
-    CCondition                     m_rcvCondition;
+    CSerialPort *                 m_port;
+    CLibCEC *                     m_controller;
+    CecBuffer<uint8_t>            m_inBuffer;
+    CecBuffer<CCECAdapterMessage> m_outBuffer;
+    CMutex                        m_bufferMutex;
+    CMutex                        m_commMutex;
+    CCondition                    m_rcvCondition;
   };
 };