2 * This file is part of the libCEC(R) library.
4 * libCEC Exynos Code is Copyright (C) 2014 Valentin Manea
5 * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
6 * libCEC(R) is an original work, containing original code.
8 * libCEC(R) is a trademark of Pulse-Eight Limited.
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 * Alternatively, you can license this library under a commercial license,
26 * please contact Pulse-Eight Licensing for more information.
28 * For more information contact:
29 * Pulse-Eight Licensing <license@pulse-eight.com>
30 * http://www.pulse-eight.com/
31 * http://www.pulse-eight.net/
36 #include <sys/ioctl.h>
39 #if defined(HAVE_EXYNOS_API)
40 #include "ExynosCEC.h"
41 #include "ExynosCECAdapterCommunication.h"
43 #include "lib/CECTypeUtils.h"
44 #include "lib/LibCEC.h"
45 #include "lib/platform/util/StdString.h"
46 #include "lib/platform/util/buffer.h"
50 using namespace PLATFORM
;
52 #define LIB_CEC m_callback->GetLib()
55 CExynosCECAdapterCommunication::CExynosCECAdapterCommunication(IAdapterCommunicationCallback
*callback
) :
56 IAdapterCommunication(callback
),
57 m_bLogicalAddressChanged(false)
59 CLockObject
lock(m_mutex
);
61 m_logicalAddresses
.Clear();
62 m_fd
= INVALID_SOCKET_VALUE
;
66 CExynosCECAdapterCommunication::~CExynosCECAdapterCommunication(void)
72 bool CExynosCECAdapterCommunication::IsOpen(void)
74 return IsInitialised() && m_fd
!= INVALID_SOCKET_VALUE
;
78 bool CExynosCECAdapterCommunication::Open(uint32_t UNUSED(iTimeoutMs
), bool UNUSED(bSkipChecks
), bool bStartListening
)
80 if (m_fd
!= INVALID_SOCKET_VALUE
)
83 if ((m_fd
= open(CEC_EXYNOS_PATH
, O_RDWR
)) > 0)
85 if (!bStartListening
|| CreateThread()) {
94 void CExynosCECAdapterCommunication::Close(void)
99 m_fd
= INVALID_SOCKET_VALUE
;
103 std::string
CExynosCECAdapterCommunication::GetError(void) const
105 std::string
strError(m_strError
);
110 cec_adapter_message_state
CExynosCECAdapterCommunication::Write(
111 const cec_command
&data
, bool &UNUSED(bRetry
), uint8_t UNUSED(iLineTimeout
), bool UNUSED(bIsReply
))
113 uint8_t buffer
[CEC_MAX_FRAME_SIZE
];
115 cec_adapter_message_state rc
= ADAPTER_MESSAGE_STATE_ERROR
;
120 if ((size_t)data
.parameters
.size
+ data
.opcode_set
> sizeof(buffer
))
122 LIB_CEC
->AddLog(CEC_LOG_ERROR
, "%s: data size too large !", __func__
);
123 return ADAPTER_MESSAGE_STATE_ERROR
;
126 buffer
[0] = (data
.initiator
<< 4) | (data
.destination
& 0x0f);
130 buffer
[1] = data
.opcode
;
133 memcpy(&buffer
[size
], data
.parameters
.data
, data
.parameters
.size
);
134 size
+= data
.parameters
.size
;
137 if (write(m_fd
, (void *)buffer
, size
) == size
)
139 rc
= ADAPTER_MESSAGE_STATE_SENT_ACKED
;
143 LIB_CEC
->AddLog(CEC_LOG_ERROR
, "%s: write failed !", __func__
);
150 uint16_t CExynosCECAdapterCommunication::GetFirmwareVersion(void)
156 cec_vendor_id
CExynosCECAdapterCommunication::GetVendorId(void)
158 return cec_vendor_id(CEC_VENDOR_SAMSUNG
);
162 uint16_t CExynosCECAdapterCommunication::GetPhysicalAddress(void)
164 uint16_t phys_addr
= CEC_DEFAULT_PADDR
;
166 FILE *f
= fopen(CEC_PADDR_NAME
, "r");
168 if(fscanf(f
, "%hu", &phys_addr
) != 1)
169 phys_addr
= CEC_DEFAULT_PADDR
;
177 cec_logical_addresses
CExynosCECAdapterCommunication::GetLogicalAddresses(void)
179 return m_logicalAddresses
;
183 bool CExynosCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses
&addresses
)
185 unsigned int log_addr
= addresses
.primary
;
186 CLockObject
lock(m_mutex
);
191 if (ioctl(m_fd
, CEC_IOC_SETLADDR
, &log_addr
))
193 LIB_CEC
->AddLog(CEC_LOG_ERROR
, "%s: IOCTL SetLogicalAddr failed !", __func__
);
196 m_logicalAddresses
= addresses
;
197 m_bLogicalAddressChanged
= true;
203 void CExynosCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address
UNUSED(oldAddress
))
205 unsigned int log_addr
= CECDEVICE_BROADCAST
;
206 if (ioctl(m_fd
, CEC_IOC_SETLADDR
, &log_addr
))
208 LIB_CEC
->AddLog(CEC_LOG_ERROR
, "%s: IOCTL SetLogicalAddr failed !", __func__
);
213 void *CExynosCECAdapterCommunication::Process(void)
215 uint8_t buffer
[CEC_MAX_FRAME_SIZE
];
218 cec_logical_address initiator
, destination
;
228 if (select(m_fd
+ 1, &rfds
, NULL
, NULL
, NULL
) >= 0 )
230 size
= read(m_fd
, buffer
, CEC_MAX_FRAME_SIZE
);
234 initiator
= cec_logical_address(buffer
[0] >> 4);
235 destination
= cec_logical_address(buffer
[0] & 0x0f);
240 cmd
, initiator
, destination
,
241 ( size
> 1 ) ? cec_opcode(buffer
[1]) : CEC_OPCODE_NONE
);
243 for( uint8_t i
= 2; i
< size
; i
++ )
244 cmd
.parameters
.PushBack(buffer
[i
]);
247 m_callback
->OnCommandReceived(cmd
);
256 #endif // HAVE_EXYNOS_API