RDK Documentation (Open Sourced RDK Components)
hdmi_cec_driver.c
1 /*
2  * If not stated otherwise in this file or this component's Licenses.txt file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2016 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 
21 
22 /**
23 * @defgroup hdmicec
24 * @{
25 * @defgroup ccec
26 * @{
27 **/
28 
29 
30 #include <stdio.h>
31 #include <fcntl.h>
32 #include <errno.h>
33 #include <stdint.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <pthread.h>
38 
39 #include "libIBus.h"
40 #include "ccec/drivers/hdmi_cec_driver.h"
41 #include "ccec/drivers/iarmbus/CecIARMBusMgr.h"
42 #include "safec_lib.h"
43 
44 #define CECDriverAssert(cond) do\
45 {\
46  if (!(cond)) {\
47  printf("Assert Failed at [%s][%d]\r\n", __FUNCTION__, __LINE__);\
48  }\
49 }while(0)
50 
51 typedef struct DriverContext_t
52 {
53  pthread_mutex_t lock;
55  void * txCBdata;
57  void * rxCBdata;
58 
60 
61 static DriverContext_t *driverCtx = 0;
62 pthread_mutex_t DriverMutex = PTHREAD_MUTEX_INITIALIZER;
63 #define DRIVER_LOCK() do{/*printf("LOCKING DRV [%s]\r\n", __FUNCTION__);*/ pthread_mutex_lock(&DriverMutex);}while(0)
64 #define DRIVER_UNLOCK() do{/*printf("UNLOCKING DRV [%s]\r\n", __FUNCTION__);*/pthread_mutex_unlock(&DriverMutex);}while(0)
65 
66 static void cecRecvEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len);
67 
68 int HdmiCecOpen(int *handle)
69 {
70  DRIVER_LOCK();
71  int retErr = HDMI_CEC_IO_SUCCESS;
72 
73  if (driverCtx == 0) {
74  {
75 #if 0
76  printf("Sending SYNC ENABLE to Daemon\r\n");
77  IARM_Result_t ret = IARM_RESULT_SUCCESS;
79  memset(&data, 0, sizeof(data));
80  data.enabled = 1;
81  IARM_Bus_Call(IARM_BUS_CECMGR_NAME,IARM_BUS_CECMGR_API_Enable,(void *)&data, sizeof(data));
82 #else
83  printf("Sending ASYNC ENABLE to Daemon\r\n");
84  IARM_Result_t ret = IARM_RESULT_SUCCESS;
86  memset(&data, 0, sizeof(data));
87  data.length = 1;
88  data.data[0]= 1;
89  /*To Do - Return values checking of IARM Calls*/
90  ret = IARM_Bus_BroadcastEvent(IARM_BUS_CECMGR_NAME, (IARM_EventId_t) IARM_BUS_CECMGR_EVENT_ENABLE, (void *)&data, sizeof(data));
91 #endif
92  }
94  driverCtx = (DriverContext_t *)malloc(sizeof(DriverContext_t));
95  *handle = (int)driverCtx;
96  retErr = HDMI_CEC_IO_SUCCESS;
97  }
98  else {
99  retErr = HDMI_CEC_IO_INVALID_STATE;
100  }
101 
102  DRIVER_UNLOCK();
103  return retErr;
104 }
105 
106 int HdmiCecClose(int handle)
107 {
108  DRIVER_LOCK();
109  CECDriverAssert(handle == ((int)driverCtx));
110 
111  int retErr = HDMI_CEC_IO_SUCCESS;
112  if (driverCtx != 0) {
113  {
114 #if 0
115  printf("Sending SYNC DISABLE to Daemon\r\n");
116  IARM_Result_t ret = IARM_RESULT_SUCCESS;
118  memset(&data, 0, sizeof(data));
119  data.enabled = 0;
120  IARM_Bus_Call(IARM_BUS_CECMGR_NAME,IARM_BUS_CECMGR_API_Enable,(void *)&data, sizeof(data));
121 #else
122  printf("Sending ASYNC DISABLE to Daemon\r\n");
123  IARM_Result_t ret = IARM_RESULT_SUCCESS;
125  memset(&data, 0, sizeof(data));
126  data.length = 1;
127  data.data[0]= 0;
128  /*To Do - Return values checking of IARM Calls*/
129  ret = IARM_Bus_BroadcastEvent(IARM_BUS_CECMGR_NAME, (IARM_EventId_t) IARM_BUS_CECMGR_EVENT_ENABLE, (void *)&data, sizeof(data));
130 #endif
131  }
133  free(driverCtx);
134  driverCtx = 0;
135  retErr = HDMI_CEC_IO_SUCCESS;
136  }
137  else {
138  retErr = HDMI_CEC_IO_INVALID_STATE;
139  }
140 
141  DRIVER_UNLOCK();
142  return retErr;
143 
144 }
145 
146 int HdmiCecAddLogicalAddress(int handle, int logicalAddresses)
147 {
148  DRIVER_LOCK();
149  CECDriverAssert(handle == ((int)driverCtx));
150  int retErr = HDMI_CEC_IO_SUCCESS;
151 
152  //printf("HdmiCecAddLogicalAddress from IARM driver logicalAddresses set = %d \n", logicalAddresses);
153 
154  IARM_Result_t ret = IARM_RESULT_SUCCESS;
156 
157  memset(&data, 0, sizeof(data));
158  data.logicalAddress = logicalAddresses;
159 
160  ret = IARM_Bus_Call(IARM_BUS_CECMGR_NAME,IARM_BUS_CECMGR_API_AddLogicalAddress,(void *)&data, sizeof(data));
161  if( IARM_RESULT_SUCCESS != ret)
162  {
163  //printf("Iarm call failed retval = %d \n", ret);
164  retErr = HDMI_CEC_IO_INVALID_STATE;
165  }
166 
167  DRIVER_UNLOCK();
168 
169  return retErr;
170 }
171 
172 int HdmiCecRemoveLogicalAddress(int handle, int logicalAddresses)
173 {
174  //@TODO: IARM Call.
175  return HDMI_CEC_IO_SUCCESS;
176 }
177 
178 //int HdmiCecGetLogicalAddress(int handle, int *logicalAddresses, int *num)
179 int HdmiCecGetLogicalAddress(int handle, int devType, int *logicalAddresses)
180 {
181  DRIVER_LOCK();
182  CECDriverAssert(handle == ((int)driverCtx));
183  int retErr = HDMI_CEC_IO_SUCCESS;
184 
185  //printf("HdmiCecGetLogicalAddress from IARM driver DevType set = %d \n", devType);
186 
187  IARM_Result_t ret = IARM_RESULT_SUCCESS;
189 
190  memset(&data, 0, sizeof(data));
191  data.devType = devType;
192 
193  ret = IARM_Bus_Call(IARM_BUS_CECMGR_NAME,IARM_BUS_CECMGR_API_GetLogicalAddress,(void *)&data, sizeof(data));
194  if( IARM_RESULT_SUCCESS != ret)
195  {
196  //printf("Iarm call failed retval = %d \n", ret);
197  retErr = HDMI_CEC_IO_INVALID_STATE;
198  }
199  else
200  {
201  *logicalAddresses = data.logicalAddress;
202  }
203 
204  //printf("HdmiCecGetLogicalAddress from IARM driver Logical Address obtained = %d \n", data.logicalAddress);
205 
206  DRIVER_UNLOCK();
207 
208  return retErr;
209 }
210 
211 void HdmiCecGetPhysicalAddress(int handle, unsigned int *physicalAddresses)
212 {
213  DRIVER_LOCK();
214  CECDriverAssert(handle == ((int)driverCtx));
215  int retErr = HDMI_CEC_IO_SUCCESS;
216 
217  //printf("HdmiCecGetPhysicalAddress from IARM driver \n");
218 
219  IARM_Result_t ret = IARM_RESULT_SUCCESS;
221 
222  memset(&data, 0, sizeof(data));
223 
224  ret = IARM_Bus_Call(IARM_BUS_CECMGR_NAME,IARM_BUS_CECMGR_API_GetPhysicalAddress,(void *)&data, sizeof(data));
225  if( IARM_RESULT_SUCCESS != ret)
226  {
227  //printf("Iarm call failed retval = %d \n", ret);
228  retErr = HDMI_CEC_IO_INVALID_STATE;
229  }
230  else
231  {
232  *physicalAddresses = data.physicalAddress;
233  }
234 
235  //printf("HdmiCecGetPhysicalAddress from IARM driver Physical Address obtained = %x \n", data.physicalAddress);
236 
237  DRIVER_UNLOCK();
238 
239  return;
240 }
241 
242 int HdmiCecSetRxCallback(int handle, HdmiCecRxCallback_t cbfunc, void *data)
243 {
244  DRIVER_LOCK();
245  CECDriverAssert(handle == ((int)driverCtx));
246 
247  driverCtx->rxCB = cbfunc;
248  driverCtx->rxCBdata = data;
249 
250  DRIVER_UNLOCK();
251 
252  return HDMI_CEC_IO_SUCCESS;
253 }
254 
255 int HdmiCecSetTxCallback(int handle, HdmiCecTxCallback_t cbfunc, void *data)
256 {
257  DRIVER_LOCK();
258  CECDriverAssert(handle == ((int)driverCtx));
259 
260  driverCtx->txCB = cbfunc;
261  driverCtx->txCBdata = data;
262 
263  DRIVER_UNLOCK();
264 
265  return HDMI_CEC_IO_SUCCESS;
266 }
267 
268 int HdmiCecTxAsync(int handle, const unsigned char *buf, int len)
269 {
270  DRIVER_LOCK();
271  CECDriverAssert(handle == ((int)driverCtx));
272 
273  IARM_Bus_CECMgr_EventData_t dataToSend;
274  memset(&dataToSend, 0, sizeof(dataToSend));
275  dataToSend.length = len;
276  MEMCPY_S(dataToSend.data,sizeof(dataToSend.data), buf, len);
277  IARM_Bus_BroadcastEvent(IARM_BUS_CECMGR_NAME, (IARM_EventId_t) IARM_BUS_CECMGR_EVENT_SEND, (void *)&dataToSend, sizeof(dataToSend));
278 
279  DRIVER_UNLOCK();
280 
281  return HDMI_CEC_IO_SUCCESS;
282 }
283 
284 int HdmiCecTx(int handle, const unsigned char *buf, int len, int *result)
285 {
286  DRIVER_LOCK();
287  CECDriverAssert(handle == ((int)driverCtx));
288  IARM_Result_t ret = IARM_RESULT_SUCCESS;
289  IARM_Bus_CECMgr_Send_Param_t dataToSend;
290 
291  memset(&dataToSend, 0, sizeof(dataToSend));
292  dataToSend.length = len;
293  MEMCPY_S(dataToSend.data,sizeof(dataToSend.data), buf, len);
294  ret = IARM_Bus_Call(IARM_BUS_CECMGR_NAME,IARM_BUS_CECMGR_API_Send,(void *)&dataToSend, sizeof(dataToSend));
295  if( IARM_RESULT_SUCCESS != ret)
296  {
297  //printf("Iarm call failed retval = %d \n", ret);
298  DRIVER_UNLOCK();
299  return HDMI_CEC_IO_INVALID_STATE;
300  }
301  *result = dataToSend.retVal;
302 
303  DRIVER_UNLOCK();
304 
305  return HDMI_CEC_IO_SUCCESS;
306 }
307 
308 
309 static void cecRecvEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
310 {
312 
313  /* call the callback */
314  if (driverCtx->rxCB) {
315  //printf("CEC IARM Driver GOT messages =============\r\n");
316 
317  driverCtx->rxCB((int)driverCtx, driverCtx->rxCBdata, cecEventData->data, cecEventData->length);
318  }
319  else {
320  //printf("CEC IARM Driver Dropping messages for lack of listeners\r\n");
321  }
322 }
323 
324 int HdmiCecSetLogicalAddress(int handle, int *logicalAddresses, int num)
325 {
326  return 0;
327 }
328 
329 //int main()
330 //{
331 //
332 // int handle = 0;
333 // int result = 0;
334 // IARM_Bus_Init("CECClient");
335 // IARM_Bus_Connect();
336 // HdmiCecOpen(&handle);
337 // unsigned char buf[2] = {0x30, 0x36};
338 // HdmiCecTxAsync(handle, buf, 2);
339 //
340 // sleep(10);
341 //
342 // HdmiCecClose(handle);
343 //
344 // IARM_Bus_Disconnect();
345 // IARM_Bus_Term();
346 //}
347 
348 
349 
350 
351 /** @} */
352 /** @} */
HdmiCecSetRxCallback
int HdmiCecSetRxCallback(int handle, HdmiCecRxCallback_t cbfunc, void *data)
Sets CEC packet Receive callback.
Definition: hdmi_cec_driver.c:242
_CECMgr_EventData_t
Definition: CecIARMBusMgr.h:66
HdmiCecTxCallback_t
void(* HdmiCecTxCallback_t)(int handle, void *callbackData, int result)
Definition: hdmi_cec_driver.h:164
IARM_Bus_Call
IARM_Result_t IARM_Bus_Call(const char *ownerName, const char *methodName, void *arg, size_t argLen)
This API is used to Invoke RPC method by its application name and method name.
Definition: iarm_bus.c:57
HdmiCecClose
int HdmiCecClose(int handle)
close an instance of CEC driver. This function should close the currently opened driver instance.
Definition: hdmi_cec_driver.c:106
IARM_BUS_CECMGR_EVENT_ENABLE
@ IARM_BUS_CECMGR_EVENT_ENABLE
Definition: CecIARMBusMgr.h:54
IARM_BUS_CECMGR_EVENT_SEND
@ IARM_BUS_CECMGR_EVENT_SEND
Definition: CecIARMBusMgr.h:52
_IARM_Bus_CECMgr_GetPhysicalAddress_Param_t
Definition: CecIARMBusMgr.h:87
IARM_BUS_CECMGR_NAME
#define IARM_BUS_CECMGR_NAME
Definition: CecIARMBusMgr.h:41
HdmiCecRxCallback_t
void(* HdmiCecRxCallback_t)(int handle, void *callbackData, unsigned char *buf, int len)
Definition: hdmi_cec_driver.h:158
HdmiCecOpen
int HdmiCecOpen(int *handle)
opens an instance of CEC driver. This function should be call once before the functions in this API...
Definition: hdmi_cec_driver.c:68
IARM_Bus_RegisterEventHandler
IARM_Result_t IARM_Bus_RegisterEventHandler(const char *ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler)
This API register to listen to event and provide the callback function for event notification....
Definition: iarmMgrMocks.cpp:43
HdmiCecGetLogicalAddress
int HdmiCecGetLogicalAddress(int handle, int devType, int *logicalAddresses)
Get the Logical Addresses claimed by host device.
Definition: hdmi_cec_driver.c:179
_IARM_Bus_CECMgr_AddLogicalAddress_Param_t
Definition: CecIARMBusMgr.h:82
IARM_Bus_BroadcastEvent
IARM_Result_t IARM_Bus_BroadcastEvent(const char *ownerName, IARM_EventId_t eventId, void *data, size_t len)
This API is used to publish an Asynchronous event to all IARM client registered for this perticular e...
HdmiCecTx
int HdmiCecTx(int handle, const unsigned char *buf, int len, int *result)
Writes CEC packet onto bus.
Definition: hdmi_cec_driver.c:284
libIBus.h
RDK IARM-Bus API Declarations.
HdmiCecTxAsync
int HdmiCecTxAsync(int handle, const unsigned char *buf, int len)
Writes CEC packet onto bus asynchronously.
Definition: hdmi_cec_driver.c:268
HdmiCecGetPhysicalAddress
void HdmiCecGetPhysicalAddress(int handle, unsigned int *physicalAddresses)
Get the Physical Address obtained by the driver.
Definition: hdmi_cec_driver.c:211
HdmiCecRemoveLogicalAddress
int HdmiCecRemoveLogicalAddress(int handle, int logicalAddresses)
Clear the Logical Addresses claimed by host device.
Definition: hdmi_cec_driver.c:172
_IARM_Bus_CECMgr_Enable_Param_t
Definition: CecIARMBusMgr.h:91
DriverContext_t
Definition: hdmi_cec_driver.c:51
_IARM_Bus_CECMgr_GetLogicalAddress_Param_t
Definition: CecIARMBusMgr.h:77
IARM_Bus_UnRegisterEventHandler
IARM_Result_t IARM_Bus_UnRegisterEventHandler(const char *ownerName, IARM_EventId_t eventId)
This API is used to Remove ALL handlers registered for the given event. This API remove the all the e...
HdmiCecAddLogicalAddress
int HdmiCecAddLogicalAddress(int handle, int logicalAddresses)
Add one Logical Addresses to be used by host device.
Definition: hdmi_cec_driver.c:146
HdmiCecSetTxCallback
int HdmiCecSetTxCallback(int handle, HdmiCecTxCallback_t cbfunc, void *data)
Sets CEC packet Transmit callback.
Definition: hdmi_cec_driver.c:255
IARM_BUS_CECMGR_EVENT_RECV
@ IARM_BUS_CECMGR_EVENT_RECV
Definition: CecIARMBusMgr.h:53
_IARM_Bus_CECMgr_Send_Param_t
Definition: CecIARMBusMgr.h:71
HdmiCecSetLogicalAddress
int HdmiCecSetLogicalAddress(int handle, int *logicalAddresses, int num)
This API is DEPRECATED due to possible race conditions competing for a logical address.
Definition: hdmi_cec_driver.c:324