RDK Documentation (Open Sourced RDK Components)
irMgr.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 iarmmgrs
24 * @{
25 * @defgroup ir
26 * @{
27 **/
28 
29 
30 #include <stdio.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <time.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include "libIARM.h"
38 #include "iarmUtil.h"
39 #include "plat_ir.h"
40 #include "comcastIrKeyCodes.h"
41 #include "irMgr.h"
42 #include "irMgrInternal.h"
43 #include "libIBus.h"
44 #include "sysMgr.h"
45 #include <pthread.h>
46 #include <errno.h>
47 #include "manager.hpp"
48 #include "rfcapi.h"
49 #include "iarmcec.h"
50 
51 #define MAX_KEY_REPEATS 6
52 #define LAST_KEY_NUM_SECONDS 2
53 #define MICRO_SECS_PER_SEC 1000000L
54 #define MICROSECS_PER_MILLISEC 1000L
55 
56 // Log translate event helper macro
57 #define LOG_TRANSLATE_EVENT(OLD_KEY,NEW_KEY) LOG("IR Key " #OLD_KEY "(0x%x) event is translated to " #NEW_KEY "(0x%x)\n", \
58  (unsigned int)OLD_KEY, (unsigned int)NEW_KEY)
59 
60 static pthread_t eRepeatThreadID;
61 static pthread_mutex_t tLastKeyMutex;
62 static pthread_mutex_t tKeySeqMutex;
63 static pthread_mutex_t tMutexLock;
64 static pthread_cond_t tMutexCond;
65 static int gCurrentKeyCode = KED_UNDEFINEDKEY;
66 static int gCurrentKeySrcId = 0;
67 static const unsigned int gInitialWaitTimeout = 500;
68 static unsigned int gRepeatKeyInterval = 50;
69 static int numKeyRepeats = 0;
70 static int keyLogStatus = 1;
71 
72 #ifndef NO_RF4CE
73 #ifdef RF4CE_GENMSO_API
74 clock_t Rf4ceAutoBindClock=0;
75 static pthread_t eRf4ceAutoBindOffThreadID;
76 static void* _Rf4ceAutoBindOffThreadFunc(void *arg);
77 int getTimeMs();
78 #elif defined(RF4CE_API)
79 clock_t Rf4ceAutoBindClock=0;
80 static pthread_t eRf4ceAutoBindOffThreadID;
81 static void* _Rf4ceAutoBindOffThreadFunc(void *arg);
82 int getTimeMs();
83 #elif defined(RF4CE_GPMSO_API)
84 clock_t Rf4ceAutoBindClock=0;
85 static pthread_t eRf4ceAutoBindOffThreadID;
86 static void* _Rf4ceAutoBindOffThreadFunc(void *arg);
87 int getTimeMs();
88 #else
89 #warning "No RF4CE API defined"
90 #endif
91 #endif // NO_RF4CE
92 
93 //For handling LAST key as an exit key when holding it down
94 static pthread_t eLASTKeyTimerThreadID;
95 static void* _LASTKeyTimerThreadFunc(void *arg);
96 bool bLastKeyUpReceived = false;
97 bool bLastTimerRunning = false;
98 bool bIgnoreLastKeyup = false;
99 int LASTkeySrc = IARM_BUS_IRMGR_KEYSRC_IR;
100 int lastKeyNumMSecs = 1500;
101 static bool isCecLocalLogicEnabled = false;
102 
103 /*Default is IR*/
104 static bool bNeedRFKeyUp = false;
105 
106 static void* _KeyRepeatThreadFunc (void *arg);
107 #ifdef XMP_TAG_OWNER_SUPPORT
108  static void _IrKeyCallback(PLAT_irKey_metadata_t *irKey);
109  static void _IrKeyPairing(PLAT_irKey_metadata *irKey);
110  static void _IrKeyCallbackFrom(PLAT_irKey_metadata *irKey, int keySrc, unsigned int keySrcId);
111  static void _IrInputKeyEventHandler(PLAT_irKey_metadata_t *irKey, int keySrc, unsigned int keySrcId);
112 #else
113  static void _IrKeyCallback(int keyType, int keyCode);
114  static void _IrKeyCallbackFrom(int keyType, int keyCode, int keySrc, unsigned int keySrcId);
115  static void _IrInputKeyEventHandler(int keyType, int keyCode, int keySrc, unsigned int keySrcId);
116 #endif
117 static void _logEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len);
118 
119 #ifndef NO_RF4CE
120 #ifdef USE_UNIFIED_CONTROL_MGR_API_1
121 #include "ctrlm_ipc.h"
122 #include "ctrlm_ipc_rcu.h"
123  static void _ctrlmEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len);
124 #else
125 #ifdef RF4CE_GENMSO_API
126 #include "rf4ceMgr.h"
127  static void _rfEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len);
128 #elif defined(RF4CE_API)
129 #include "rf4ceMgr.h"
130  static void _rf4ceEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len);
131 #elif defined(RF4CE_GPMSO_API)
132 #include "rf4ceMgr.h"
133  static void _gpEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len);
134 #else
135 #warning "No RF4CE API defined"
136 #endif
137 #endif // USE_UNIFIED_CONTROL_MGR_API_1
138 #endif // NO_RF4CE
139 
140 static IARM_Result_t _SetRepeatInterval(void *arg);
141 static IARM_Result_t _GetRepeatInterval(void *arg);
142 
143 static uinput_dispatcher_t udispatcher = NULL;
144 
145 IARM_Result_t IRMgr_Register_uinput(uinput_dispatcher_t f)
146 {
147  udispatcher = f;
148  return IARM_RESULT_SUCCESS;
149 }
150 
151 IARM_Result_t IRMgr_Start(int argc, char *argv[])
152 {
153  char *settingsFile = NULL;
154 
155  if (argc == 2) settingsFile = argv[1];
156 
157  LOG("Entering [%s] - [%s] - disabling io redirect buf\r\n", __FUNCTION__, IARM_BUS_IRMGR_NAME);
158  setvbuf(stdout, NULL, _IOLBF, 0);
159 
160  PLAT_API_INIT();
161 
167 
168 #ifndef NO_RF4CE
169  #ifdef USE_UNIFIED_CONTROL_MGR_API_1
170  IARM_Bus_RegisterEventHandler(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_KEY_PRESS, _ctrlmEventHandler);
171  IARM_Bus_RegisterEventHandler(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_KEY_GHOST, _ctrlmEventHandler);
172  IARM_Bus_RegisterEventHandler(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_FUNCTION, _ctrlmEventHandler);
173  #else
174  #ifdef RF4CE_GENMSO_API
175  IARM_Bus_RegisterEventHandler(IARM_BUS_RFMGR_NAME, IARM_BUS_RFMGR_EVENT_KEY, _rfEventHandler);
176  #elif defined(RF4CE_API)
177  IARM_Bus_RegisterEventHandler(IARM_BUS_RF4CEMGR_NAME, IARM_BUS_RF4CEMGR_EVENT_KEY, _rf4ceEventHandler);
178  #elif defined(RF4CE_GPMSO_API)
179  IARM_Bus_RegisterEventHandler(IARM_BUS_GPMGR_NAME, IARM_BUS_GPMGR_EVENT_KEY, _gpEventHandler);
180  #else
181  #warning "No RF4CE API defined"
182  #endif
183  #endif // USE_UNIFIED_CONTROL_MGR_API_1
184 #endif // NO_RF4CE
185 
187  IARM_Bus_Call(IARM_BUS_SYSMGR_NAME, IARM_BUS_SYSMGR_API_GetKeyCodeLoggingPref, (void *)&param, sizeof(param));
188  keyLogStatus = param.logStatus;
189 
190  pthread_mutex_init (&tKeySeqMutex, NULL);
191  pthread_mutex_init (&tMutexLock, NULL);
192  pthread_mutex_init (&tLastKeyMutex, NULL);
193  pthread_cond_init (&tMutexCond, NULL);
194  pthread_create (&eRepeatThreadID, NULL, _KeyRepeatThreadFunc, NULL);
195 
196 #ifdef XMP_TAG_OWNER_SUPPORT
198 #else
199  PLAT_API_RegisterIRKeyCallback(_IrKeyCallback);
200 #endif
202 
203  try {
205  }
206  catch (...){
207  LOG("Exception Caught during [device::Manager::Initialize]\r\n");
208  }
209 
210  RFC_ParamData_t rfcParam;
211  WDMP_STATUS status = getRFCParameter("TestComponent", "Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.CECLocalLogic.Enable", &rfcParam);
212  if(strncasecmp(rfcParam.value, "true",4) == 0)
213  {
214  isCecLocalLogicEnabled= true;
215  LOG("RFC CEC Local Logic feature enabled \r\n");
216  }
217 
218  return IARM_RESULT_SUCCESS;
219 }
220 
221 IARM_Result_t IRMgr_Loop()
222 {
223  time_t curr = 0;
224  while(1)
225  {
226  time(&curr);
227  PLAT_API_LOOP();
228  LOG("I-ARM IR Mgr: HeartBeat at %s\r\n", ctime(&curr));
229  sleep(300);
230  }
231  return IARM_RESULT_SUCCESS;
232 }
233 
234 
235 IARM_Result_t IRMgr_Stop(void)
236 {
237 #ifndef NO_RF4CE
238  #ifdef USE_UNIFIED_CONTROL_MGR_API_1
239  IARM_Bus_RemoveEventHandler(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_KEY_PRESS, _ctrlmEventHandler);
240  IARM_Bus_RemoveEventHandler(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_KEY_GHOST, _ctrlmEventHandler);
241  IARM_Bus_RemoveEventHandler(CTRLM_MAIN_IARM_BUS_NAME, CTRLM_RCU_IARM_EVENT_FUNCTION, _ctrlmEventHandler);
242  #endif // USE_UNIFIED_CONTROL_MGR_API_1
243 #endif // NO_RF4CE
244 
246  try {
248  }
249  catch (...){
250  LOG("Exception Caught during [device::Manager::DeInitialize]\r\n");
251  }
252 
254  IARM_Bus_Term();
255  PLAT_API_TERM();
256  pthread_mutex_destroy (&tKeySeqMutex);
257  pthread_mutex_destroy (&tMutexLock);
258  pthread_mutex_destroy (&tLastKeyMutex);
259  pthread_cond_destroy (&tMutexCond);
260 
261  return IARM_RESULT_SUCCESS;
262 }
263 
264 /**
265  * @brief Sets key repeat interval
266  *
267  * This functions sets/updates the interval between two KET_KEYREPEAT events
268  *
269  * @param callCtx: Context to the caller function
270  *
271  * @param methodID: Method to be invoke
272  *
273  * @param arg: Specifies the timeout to be set
274  *
275  * @param serial: Handshake code to share with
276  *
277  * @return None
278  */
279 static IARM_Result_t _SetRepeatInterval(void *arg)
280 {
282  __TIMESTAMP(); LOG ("The timeout interval is set to %dms\n", param->timeout);
283  gRepeatKeyInterval = param->timeout;
284  return IARM_RESULT_SUCCESS;
285 }
286 
287 /**
288  * @brief Gets key repeat interval
289  *
290  * This functions sets/updates the interval between two KET_KEYREPEAT events
291  *
292  * @param callCtx: Context to the caller function
293  *
294  * @param methodID: Method to be invoke
295  *
296  * @param arg: Receives the timeout that is set
297  *
298  * @param serial: Handshake code to share with
299  *
300  * @return None
301  */
302 static IARM_Result_t _GetRepeatInterval(void *arg)
303 {
305  __TIMESTAMP(); LOG ("The timeout interval is set to %dms\n", gRepeatKeyInterval);
306  param->timeout = gRepeatKeyInterval;
307  return IARM_RESULT_SUCCESS;
308 }
309 
310 #ifndef XMP_TAG_OWNER_SUPPORT
311 static void _IrKeyCallback(int keyType, int keyCode)
312 {
313 
314  _IrKeyCallbackFrom(keyType, keyCode, IARM_BUS_IRMGR_KEYSRC_IR, 0x0);
315 
316 }
317 #else
318 static void _IrKeyCallback(PLAT_irKey_metadata_t *irKey)
319 {
320  __TIMESTAMP(); LOG("IR Key received (%x, %x, %x, %x)\n", irKey->tag,
321  irKey->owner,
322  irKey->type,
323  irKey->code);
324 #ifdef PLATCO
325  if (irKey->tag != XMP_TAG_PLATCO)
326  {
327  __TIMESTAMP(); LOG("IR Key tag is invalid (%x != %x)\n", irKey->tag, XMP_TAG_PLATCO);
328  return;
329  }
330  else
331  {
332  switch (irKey->owner)
333  {
334  case XMP_OWNER_NORMAL:
335  _IrKeyCallbackFrom(irKey, IARM_BUS_IRMGR_KEYSRC_IR, 0x0);
336  break;
337  case XMP_OWNER_PAIRING:
338  _IrKeyPairing(irKey);
339  break;
340  case XMP_OWNER_UNDEFINED:
341  default:
342  __TIMESTAMP(); LOG("Unknown owner field %x\n", irKey->owner);
343  break;
344  }
345  }
346 #else
347  bool tag_is_valid = true;
348  bool owner_is_valid = false;
349 
350  switch (irKey->owner)
351  {
352  case XMP_OWNER_NORMAL:
353  case XMP_OWNER_PAIRING:
354  owner_is_valid = true;
355  break;
356  case XMP_OWNER_UNDEFINED:
357  default:
358  __TIMESTAMP(); LOG("Unknown owner field %x\n", irKey->owner);
359  break;
360  }
361 
362  switch (irKey->tag)
363  {
364  case XMP_TAG_PLATCO:
365  tag_is_valid = false;
366  break;
367  case XMP_TAG_COMCAST:
368  case XMP_TAG_XR11V2:
369  case XMP_TAG_XR15V1:
370  case XMP_TAG_XR15V2:
371  case XMP_TAG_XR16V1:
372  case XMP_TAG_XRAV1:
373  case XMP_TAG_XR20V1:
374  break;
375  default:
376  __TIMESTAMP(); LOG("Unknown tag field %x\n", irKey->tag);
377  break;
378  }
379 
380  if (tag_is_valid && owner_is_valid) {
381  _IrKeyCallbackFrom(irKey, IARM_BUS_IRMGR_KEYSRC_IR, 0x0);
382  }
383 #endif
384 }
385 
386 static void _IrKeyPairing(PLAT_irKey_metadata_t *irKey)
387 {
388  IARM_Result_t result;
389  ctrlm_main_iarm_call_status_t status;
390  ctrlm_iarm_call_StartPairWithCode_params_t pair_data;
391 
392  if (irKey->tag != XMP_TAG_PLATCO || irKey->owner != XMP_OWNER_PAIRING)
393  {
394  return;
395  }
396 
397  memset(&status, 0, sizeof(ctrlm_main_iarm_call_status_t));
398  memset(&pair_data, 0, sizeof(ctrlm_iarm_call_StartPairWithCode_params_t));
399  status.api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION;
400  pair_data.api_revision = CTRLM_MAIN_IARM_BUS_API_REVISION;
401  pair_data.pair_code = irKey->code;
402 
403  result = IARM_Bus_Call(CTRLM_MAIN_IARM_BUS_NAME,
404  CTRLM_MAIN_IARM_CALL_STATUS_GET,
405  (void *) &status,
406  sizeof(status));
407 
408  if (result != IARM_RESULT_SUCCESS)
409  {
410  __TIMESTAMP(); LOG("%s: Failed = %d\n", CTRLM_MAIN_IARM_CALL_STATUS_GET,
411  result);
412  return;
413  }
414 
415  for (int i = 0; i < status.network_qty; i++)
416  {
417  if (status.networks[i].type == CTRLM_NETWORK_TYPE_BLUETOOTH_LE)
418  {
419  pair_data.network_id = status.networks[i].id;
420 
421  result = IARM_Bus_Call(CTRLM_MAIN_IARM_BUS_NAME,
422  CTRLM_MAIN_IARM_CALL_START_PAIR_WITH_CODE,
423  (void *) &pair_data,
424  sizeof(ctrlm_iarm_call_StartPairWithCode_params_t));
425 
426  if (result != IARM_RESULT_SUCCESS)
427  {
428  __TIMESTAMP(); LOG("%s: Failed = %d\n", CTRLM_MAIN_IARM_CALL_START_PAIR_WITH_CODE,
429  result);
430  }
431  }
432  }
433 }
434 #endif
435 
436 #ifndef XMP_TAG_OWNER_SUPPORT
437 static void _IrKeyCallbackFrom(int keyType, int keyCode, int keySrc, unsigned int keySrcId)
438 #else
439 static void _IrKeyCallbackFrom(PLAT_irKey_metadata_t *irKey, int keySrc, unsigned int keySrcId)
440 #endif
441 {
442 #ifdef XMP_TAG_OWNER_SUPPORT
443  int keyType = irKey->type;
444  int keyCode = irKey->code;
445 #endif
446  /**
447  * Ignore all the repeat keys that is trigger by MAF and instead handle only PRESS & RELEASE.
448  * The _KeyRepeatThreadFunc will manage posting KET_KEYREPEAT keys.
449  */
450  if (keyType == KET_KEYDOWN)
451  {
452  pthread_mutex_lock(&tMutexLock);
453  gCurrentKeyCode = keyCode;
454  gCurrentKeySrcId = keySrcId;
455 
456 #ifndef XMP_TAG_OWNER_SUPPORT
457  _IrInputKeyEventHandler (keyType, keyCode, keySrc, keySrcId);
458 #else
459  _IrInputKeyEventHandler (irKey, keySrc, keySrcId);
460 #endif
461  pthread_cond_signal(&tMutexCond);
462  pthread_mutex_unlock(&tMutexLock);
463  }
464  else if (keyType == KET_KEYUP)
465  {
466  pthread_mutex_lock(&tMutexLock);
467  gCurrentKeyCode = KED_UNDEFINEDKEY;
468  gCurrentKeySrcId = keySrcId;
469 
470 #ifndef XMP_TAG_OWNER_SUPPORT
471  _IrInputKeyEventHandler (keyType, keyCode, keySrc, keySrcId);
472 #else
473  _IrInputKeyEventHandler (irKey, keySrc, keySrcId);
474 #endif
475  pthread_cond_signal(&tMutexCond);
476  pthread_mutex_unlock(&tMutexLock);
477  }
478 }
479 
480 /**
481  * @brief Calback funtion to that is registered with MAF to get notified for the key press
482  *
483  * This functions receives KET_KEYDOWN, KET_KEYREPEAT and KET_KEYUP and signals the thread.
484  *
485  * @param keyType: Type of event (KEYDOWN or KEYREPEAT or KEYUP)
486  *
487  * @param keyCode: Contains the key code that is trigger by the user
488  *
489  * @param keySrc: Contains the key source that is trigger by the user
490  *
491  * @return None
492  */
493 #ifndef XMP_TAG_OWNER_SUPPORT
494 static void _IrInputKeyEventHandler(int keyType, int keyCode , int keySrc, unsigned int keySrcId)
495 #else
496 static void _IrInputKeyEventHandler(PLAT_irKey_metadata_t *irKey, int keySrc, unsigned int keySrcId)
497 #endif
498 {
499  static IARM_Bus_IRMgr_EventData_t prevEventData = { { { KET_KEYUP , KED_UNDEFINEDKEY, XMP_TAG_UNDEFINED, XMP_OWNER_UNDEFINED, 0, IARM_BUS_IRMGR_KEYSRC_IR } } } ;
500 #ifdef XMP_TAG_OWNER_SUPPORT
501  int keyType = irKey->type;
502  int keyCode = irKey->code;
503 #endif
504  static bool xr15_or_newer_notify_call = false;
505 
506  if(0 != keyLogStatus)
507  LOG("COMCAST IR Key (%x, %x, %x) From Remote Device received\r\n", keyType, keyCode, keySrcId);
508 
509 
510 #ifndef NO_RF4CE
511 #ifndef USE_UNIFIED_CONTROL_MGR_API_1
512 #ifdef RF4CE_GENMSO_API
513 
514  if(keyCode==KED_RF_PAIR_GHOST && keyType == KET_KEYDOWN){
515  MSOBusAPI_Packet_t setPacket;
516 
517  setPacket.msgId = MSOBusAPI_MsgId_AutoBind_LineOfSight; // 0x0A
518  setPacket.index = 0;
519  setPacket.length = 1;
520  setPacket.msg.CheckStatus = 1; //Set or clear
521 
522  int rc = IARM_Bus_Call(IARM_BUS_RFMGR_NAME, IARM_BUS_RFMGR_MsgRequest, (void *)&setPacket, sizeof(setPacket));
523  if(rc >= 0)
524  {
525  if(Rf4ceAutoBindClock!=0) // already in autobind
526  {
527  // just set binding and not start a new thread
528  Rf4ceAutoBindClock = getTimeMs();
529  }else{
530  // set binding time and start thread to shut it off
531  Rf4ceAutoBindClock = getTimeMs();
532  pthread_create (&eRf4ceAutoBindOffThreadID, NULL, _Rf4ceAutoBindOffThreadFunc, NULL);
533  }
534 
535  LOG("setting autoBind-LineOfSight successful\n");
536  }
537  else if(rc < 0)
538  {
539  LOG("failed setting autoBind-LineOfSight with %d\n",rc);
540  }
541 
542  }
543 #elif defined(RF4CE_API)
544  if(keyCode==KED_RF_PAIR_GHOST && keyType == KET_KEYDOWN){
545  rf4ce_Packet_t setPacket;
546 
547  setPacket.msgId = rf4ce_MsgId_AutoBind_LineOfSight; // 0x0A
548  setPacket.index = 0;
549  setPacket.length = 1;
550  setPacket.msg.CheckStatus = 1; //Set or clear
551 
552  int rc = IARM_Bus_Call(IARM_BUS_RF4CEMGR_NAME, IARM_BUS_RF4CEMGR_MsgRequest, (void *)&setPacket, sizeof(setPacket));
553  if(rc >= 0)
554  {
555  if(Rf4ceAutoBindClock!=0) // already in autobind
556  {
557  // just set binding and not start a new thread
558  Rf4ceAutoBindClock = getTimeMs();
559  }else{
560  // set binding time and start thread to shut it off
561  Rf4ceAutoBindClock = getTimeMs();
562  pthread_create (&eRf4ceAutoBindOffThreadID, NULL, _Rf4ceAutoBindOffThreadFunc, NULL);
563  }
564 
565  LOG("setting autoBind-LineOfSight successful\n");
566  }
567  else if(rc < 0)
568  {
569  LOG("failed setting autoBind-LineOfSight with %d\n",rc);
570  }
571 
572  }
573 
574 #elif defined(RF4CE_GPMSO_API)
575 
576  if(keyCode==KED_RF_PAIR_GHOST && keyType == KET_KEYDOWN){
577  gpMSOBusAPI_Packet_t setPacket;
578 
579  setPacket.msgId = gpMSOBusAPI_MsgId_AutoBind_LineOfSight; // 0x0A
580  setPacket.index = 0;
581  setPacket.length = 1;
582  setPacket.msg.CheckStatus = 1; //Set or clear
583 
584  int rc = IARM_Bus_Call(IARM_BUS_GPMGR_NAME, IARM_BUS_GPMGR_API_MsgRequest, (void *)&setPacket, sizeof(setPacket));
585  if(rc >= 0)
586  {
587  if(Rf4ceAutoBindClock!=0) // already in autobind
588  {
589  // just set binding and not start a new thread
590  Rf4ceAutoBindClock = getTimeMs();
591  }else{
592  // set binding time and start thread to shut it off
593  Rf4ceAutoBindClock = getTimeMs();
594  pthread_create (&eRf4ceAutoBindOffThreadID, NULL, _Rf4ceAutoBindOffThreadFunc, NULL);
595  }
596 
597  LOG("setting autoBind-LineOfSight successful\n");
598  }
599  else if(rc < 0)
600  {
601  LOG("failed setting autoBind-LineOfSight with %d\n",rc);
602  }
603 
604  }
605 #else
606 #warning "No RF4CE API defined"
607 #endif
608 #endif // USE_UNIFIED_CONTROL_MGR_API_1
609 #endif // NO_RF4CE
610 
611  switch(keyCode)
612  {
613 
614  case KED_RF_PAIR_GHOST:
615 #ifndef USE_UNIFIED_CONTROL_MGR_API_1
616  {
617  LOG("Auto-binding key. Don't pass on.\n");
618  return;
619  }
620 #endif
621  case KED_VOLUME_OPTIMIZE:
622  case KED_XR11_NOTIFY:
623  case KED_XR15V1_NOTIFY:
624  case KED_XR16V1_NOTIFY:
625  case KED_SCREEN_BIND_NOTIFY:
626  case KED_VOLUMEUP:
627  case KED_VOLUMEDOWN:
628  case KED_MUTE:
629  case KED_TVPOWER:
630  case KED_INPUTKEY:
631  case KED_PUSH_TO_TALK:
632  case KED_XR2V3:
633  case KED_XR5V2:
634  case KED_XR11V2:
635  case KED_XR13:
636  {
637  if (KET_KEYDOWN == keyType)
638  {
639  if (keyCode == KED_PUSH_TO_TALK && xr15_or_newer_notify_call == false)
640  {
641 #ifndef XMP_TAG_OWNER_SUPPORT
642  _IrInputKeyEventHandler(KET_KEYDOWN, KED_XR11_NOTIFY, keySrc, keySrcId);
643 #else
644  irKey->type = KET_KEYDOWN;
645  irKey->code = KED_XR11_NOTIFY;
646  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
647 #endif
648  }
649 
650  LOG("IR Control Event: keyCode: 0x%x, keySrc: 0x%x.\n", keyCode, keySrc);
651  pthread_mutex_lock(&tKeySeqMutex);
652  IARM_Bus_IRMgr_EventData_t eventData;
653  eventData.data.irkey.keyType = KET_KEYDOWN;
654  eventData.data.irkey.keyCode = keyCode;
655 #ifdef XMP_TAG_OWNER_SUPPORT
656  eventData.data.irkey.keyTag = irKey->tag;
657  eventData.data.irkey.keyOwner = irKey->owner;
658 #else
659  eventData.data.irkey.keyTag = XMP_TAG_UNDEFINED;
660  eventData.data.irkey.keyOwner = XMP_OWNER_UNDEFINED;
661 #endif
662  eventData.data.irkey.keySrc = (IARM_Bus_IRMgr_KeySrc_t)keySrc;
663  eventData.data.irkey.keySourceId = keySrcId;
664  IARM_Bus_BroadcastEvent(IARM_BUS_IRMGR_NAME, (IARM_EventId_t) IARM_BUS_IRMGR_EVENT_CONTROL, (void *)&eventData, sizeof(eventData));
665  pthread_mutex_unlock(&tKeySeqMutex);
666  }
667  return;
668  }
669  // Handle LAST
670  case KED_LAST:
671  {
672  //On LAST keydown
673  if (KET_KEYDOWN == keyType)
674  {
675  pthread_mutex_lock(&tKeySeqMutex);
676 
677  //Clear flag - LAST keyup not received
678  bLastKeyUpReceived = false;
679 
680  //Clear flag - look for LAST keyup
681  bIgnoreLastKeyup = false;
682 
683  //Keep the keySrc needed for the timer
684  LASTkeySrc = keySrc;
685 
686  //If the timer is not already running...
687  if(bLastTimerRunning == false)
688  {
689  //Start LAST key timer thread
690 #ifndef XMP_TAG_OWNER_SUPPORT
691  pthread_create (&eLASTKeyTimerThreadID, NULL, _LASTKeyTimerThreadFunc, NULL);
692 #else
693  pthread_create (&eLASTKeyTimerThreadID, NULL, _LASTKeyTimerThreadFunc, (void *)irKey);
694 #endif
695  }
696 
697  pthread_mutex_unlock(&tKeySeqMutex);
698  }
699  //ON LAST keyup
700  else if (KET_KEYUP == keyType)
701  {
702  pthread_mutex_lock(&tKeySeqMutex);
703 
704  //Set flag that LAST keyup was received
705  bLastKeyUpReceived = true;
706 
707  //If we're not ignoring the LAST keyup, send the LAST keydown and keyup
708  if(bIgnoreLastKeyup == false)
709  {
710  IARM_Bus_IRMgr_EventData_t eventData;
711  LOG("Sending LAST key, not the EXIT key\n");
712 
713  // Send Key Down
714  eventData.data.irkey.keyType = KET_KEYDOWN;
715  eventData.data.irkey.keyCode = KED_LAST;
716 #ifdef XMP_TAG_OWNER_SUPPORT
717  eventData.data.irkey.keyTag = irKey->tag;
718  eventData.data.irkey.keyOwner = irKey->owner;
719 #else
720  eventData.data.irkey.keyTag = XMP_TAG_UNDEFINED;
721  eventData.data.irkey.keyOwner = XMP_OWNER_UNDEFINED;
722 #endif
723  eventData.data.irkey.isFP = 0;
724  eventData.data.irkey.keySrc = (_IRMgr_KeySrc_t)keySrc;
725  eventData.data.irkey.keySourceId = keySrcId;
726  if (udispatcher){
727  udispatcher(eventData.data.irkey.keyCode, eventData.data.irkey.keyType, eventData.data.irkey.keySrc);
728  }
729  IARM_Bus_BroadcastEvent(IARM_BUS_IRMGR_NAME, (IARM_EventId_t) IARM_BUS_IRMGR_EVENT_IRKEY, (void *)&eventData, sizeof(eventData));
730 
731  // Send Key UP
732  eventData.data.irkey.keyType = KET_KEYUP;
733  if (udispatcher){
734  udispatcher(eventData.data.irkey.keyCode, eventData.data.irkey.keyType, eventData.data.irkey.keySrc);
735  }
736  IARM_Bus_BroadcastEvent(IARM_BUS_IRMGR_NAME, (IARM_EventId_t) IARM_BUS_IRMGR_EVENT_IRKEY, (void *)&eventData, sizeof(eventData));
737  }
738 
739  pthread_mutex_unlock(&tKeySeqMutex);
740  }
741 
742  return;
743  }
744  case KED_SELECT:
745  if ((KET_KEYDOWN == keyType) && (xr15_or_newer_notify_call == false) && (keySrc == IARM_BUS_IRMGR_KEYSRC_IR))
746  {
747 #ifndef XMP_TAG_OWNER_SUPPORT
748  _IrInputKeyEventHandler(KET_KEYDOWN, KED_XR11_NOTIFY, keySrc, keySrcId);
749 #else
750  irKey->type = KET_KEYDOWN;
751  irKey->code = KED_XR11_NOTIFY;
752  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
753 #endif
754  }
755  break;
756  case KED_XR15V1_PUSH_TO_TALK:
757  LOG_TRANSLATE_EVENT(KED_XR15V1_PUSH_TO_TALK, KED_PUSH_TO_TALK);
758  if (KET_KEYDOWN == keyType)
759  {
760  xr15_or_newer_notify_call = true;
761 #ifndef XMP_TAG_OWNER_SUPPORT
762  _IrInputKeyEventHandler(KET_KEYDOWN, KED_XR15V1_NOTIFY, keySrc, keySrcId);
763 #else
764  irKey->type = KET_KEYDOWN;
765  irKey->code = KED_XR15V1_NOTIFY;
766  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
767 #endif
768  gCurrentKeyCode = KED_PUSH_TO_TALK;
769  }
770  else
771  {
772  xr15_or_newer_notify_call = false;
773  gCurrentKeyCode = KED_UNDEFINEDKEY;
774  }
775 #ifndef XMP_TAG_OWNER_SUPPORT
776  _IrInputKeyEventHandler(keyType, KED_PUSH_TO_TALK, keySrc, keySrcId);
777 #else
778  irKey->type = keyType;
779  irKey->code = KED_PUSH_TO_TALK;
780  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
781 #endif
782  return;
783  case KED_XR15V1_SELECT:
784  LOG_TRANSLATE_EVENT(KED_XR15V1_SELECT, KED_SELECT);
785  if (KET_KEYDOWN == keyType)
786  {
787  xr15_or_newer_notify_call = true;
788 #ifndef XMP_TAG_OWNER_SUPPORT
789  _IrInputKeyEventHandler(KET_KEYDOWN, KED_XR15V1_NOTIFY, keySrc, keySrcId);
790 #else
791  irKey->type = KET_KEYDOWN;
792  irKey->code = KED_XR15V1_NOTIFY;
793  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
794 #endif
795  gCurrentKeyCode = KED_SELECT;
796  }
797  else
798  {
799  xr15_or_newer_notify_call = false;
800  gCurrentKeyCode = KED_UNDEFINEDKEY;
801  }
802 #ifndef XMP_TAG_OWNER_SUPPORT
803  _IrInputKeyEventHandler(keyType, KED_SELECT, keySrc, keySrcId);
804 #else
805  irKey->type = keyType;
806  irKey->code = KED_SELECT;
807  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
808 #endif
809  return;
810  case KED_XR16V1_PUSH_TO_TALK:
811  LOG_TRANSLATE_EVENT(KED_XR16V1_PUSH_TO_TALK, KED_PUSH_TO_TALK);
812  if (KET_KEYDOWN == keyType)
813  {
814  xr15_or_newer_notify_call = true;
815 #ifndef XMP_TAG_OWNER_SUPPORT
816  _IrInputKeyEventHandler(KET_KEYDOWN, KED_XR16V1_NOTIFY, keySrc, keySrcId);
817 #else
818  irKey->type = KET_KEYDOWN;
819  irKey->code = KED_XR16V1_NOTIFY;
820  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
821 #endif
822  gCurrentKeyCode = KED_PUSH_TO_TALK;
823  }
824  else
825  {
826  xr15_or_newer_notify_call = false;
827  gCurrentKeyCode = KED_UNDEFINEDKEY;
828  }
829 #ifndef XMP_TAG_OWNER_SUPPORT
830  _IrInputKeyEventHandler(keyType, KED_PUSH_TO_TALK, keySrc, keySrcId);
831 #else
832  irKey->type = keyType;
833  irKey->code = KED_PUSH_TO_TALK;
834  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
835 #endif
836  return;
837  case KED_XR16V1_SELECT:
838  LOG_TRANSLATE_EVENT(KED_XR16V1_SELECT, KED_SELECT);
839  if (KET_KEYDOWN == keyType)
840  {
841  xr15_or_newer_notify_call = true;
842 #ifndef XMP_TAG_OWNER_SUPPORT
843  _IrInputKeyEventHandler(KET_KEYDOWN, KED_XR16V1_NOTIFY, keySrc, keySrcId);
844 #else
845  irKey->type = KET_KEYDOWN;
846  irKey->code = KED_XR16V1_NOTIFY;
847  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
848 #endif
849  gCurrentKeyCode = KED_SELECT;
850  }
851  else
852  {
853  xr15_or_newer_notify_call = false;
854  gCurrentKeyCode = KED_UNDEFINEDKEY;
855  }
856 #ifndef XMP_TAG_OWNER_SUPPORT
857  _IrInputKeyEventHandler(keyType, KED_SELECT, keySrc, keySrcId);
858 #else
859  irKey->type = keyType;
860  irKey->code = KED_SELECT;
861  _IrInputKeyEventHandler(irKey, keySrc, keySrcId);
862 #endif
863  return;
864 
865  default:
866  break;
867  }
868 
869  if (!(keyCode == KED_UNDEFINEDKEY))
870  {
871  pthread_mutex_lock(&tKeySeqMutex);
872  IARM_Bus_IRMgr_EventData_t eventData;
873  if ((keyCode != prevEventData.data.irkey.keyCode) &&
874  (keyType == KET_KEYDOWN) && (prevEventData.data.irkey.keyType != KET_KEYUP))
875  {
876  eventData.data.irkey.keyType = KET_KEYUP;
877  eventData.data.irkey.keyCode = prevEventData.data.irkey.keyCode;
878 #ifdef XMP_TAG_OWNER_SUPPORT
879  eventData.data.irkey.keyTag = irKey->tag;
880  eventData.data.irkey.keyOwner = irKey->owner;
881 #else
882  eventData.data.irkey.keyTag = XMP_TAG_UNDEFINED;
883  eventData.data.irkey.keyOwner = XMP_OWNER_UNDEFINED;
884 #endif
885  eventData.data.irkey.isFP = prevEventData.data.irkey.isFP;
886  eventData.data.irkey.keySrc = prevEventData.data.irkey.keySrc;
887  eventData.data.irkey.keySourceId = keySrcId;
888  if (udispatcher){
889  udispatcher(keyCode, keyType, keySrc);
890  }
891  IARM_Bus_BroadcastEvent(IARM_BUS_IRMGR_NAME, (IARM_EventId_t) IARM_BUS_IRMGR_EVENT_IRKEY, (void *)&eventData, sizeof(eventData));
892  }
893  eventData.data.irkey.keyType = keyType;
894  eventData.data.irkey.keyCode = keyCode;
895  eventData.data.irkey.keySourceId = keySrcId;
896  eventData.data.irkey.isFP = (keyCode == KED_POWER) ? 1:0; /*1 -> Front Panel , 0 -> IR or RF*/
897  eventData.data.irkey.keySrc = (keyCode == KED_POWER) ? IARM_BUS_IRMGR_KEYSRC_FP:(_IRMgr_KeySrc_t)keySrc;
898 #ifdef XMP_TAG_OWNER_SUPPORT
899  eventData.data.irkey.keyTag = irKey->tag;
900  eventData.data.irkey.keyOwner = irKey->owner;
901 #else
902  eventData.data.irkey.keyTag = XMP_TAG_UNDEFINED;
903  eventData.data.irkey.keyOwner = XMP_OWNER_UNDEFINED;
904 #endif
905 
906  /*Default to IR*/
907  prevEventData.data.irkey.isFP = (keyCode == KED_POWER) ? 1:0; /*1 -> Front Panel , 0 -> IR or RF*/
908  prevEventData.data.irkey.keySrc = (keyCode == KED_POWER) ? IARM_BUS_IRMGR_KEYSRC_FP:(_IRMgr_KeySrc_t)keySrc;
909  prevEventData.data.irkey.keyType = keyType;
910  prevEventData.data.irkey.keySourceId = keySrcId;
911  prevEventData.data.irkey.keyCode = keyCode;
912 #ifdef XMP_TAG_OWNER_SUPPORT
913  prevEventData.data.irkey.keyTag = irKey->tag;
914  prevEventData.data.irkey.keyOwner = irKey->owner;
915 #else
916  eventData.data.irkey.keyTag = XMP_TAG_UNDEFINED;
917  eventData.data.irkey.keyOwner = XMP_OWNER_UNDEFINED;
918 #endif
919  IARMCEC_SendCECActiveSource(isCecLocalLogicEnabled,keyType,keyCode);
920 #ifdef _DISABLE_KEY_POWEROFF //XITHREE-7832
921  bool broadcastEvent = true;
922  static int prevKeyType = keyType;
923 
924  if(keyCode == KED_FP_POWER) {
925  switch(keyType) {
926  case KET_KEYREPEAT:
927  if(prevKeyType == KET_KEYDOWN) {
928  keyType = KET_KEYUP;
929  }
930  else {
931  broadcastEvent = false;
932  }
933  break;
934 
935  case KET_KEYUP:
936  if(prevKeyType != KET_KEYDOWN) {
937  broadcastEvent = false;
938  }
939  break;
940 
941  default:
942  break;
943 
944  }
945  }
946  prevKeyType = keyType;
947  eventData.data.irkey.keyType = keyType;
948  if(!broadcastEvent) {
949  LOG("Discarding key event!!! keyCode: %x keyType: %x\n",keyCode,keyType);
950  pthread_mutex_unlock(&tKeySeqMutex);
951  return;
952  }
953  LOG("Broadcasting key event!!! keyCode: %x keyType: %x\n",eventData.data.irkey.keyCode,eventData.data.irkey.keyType);
954 #endif
955  if (udispatcher){
956  udispatcher(keyCode, keyType, keySrc);
957  }
958  IARM_Bus_BroadcastEvent(IARM_BUS_IRMGR_NAME, (IARM_EventId_t) IARM_BUS_IRMGR_EVENT_IRKEY, (void *)&eventData, sizeof(eventData));
959  pthread_mutex_unlock(&tKeySeqMutex);
960  }
961 }
962 
963 /**
964  * @brief Calback funtion to that is registered with MAF to get notified for the key press
965  *
966  * This function Waits for given timeout for the key to be released. Upon timeout, returns true
967  *
968  * @param uTimeoutValue: Time in milliseconds to wait for.
969  *
970  * @return true or false
971  */
972 static bool isKeyReleased (unsigned int uTimeoutValue)
973 {
974  int ret = 0;
975  struct timespec ts;
976  struct timeval tv;
977 
978  gettimeofday(&tv, NULL);
979 
980  /** Adapt absolute time to timeval first */
981  tv.tv_sec += (tv.tv_usec + uTimeoutValue * 1000L ) / 1000000;
982  tv.tv_usec = (tv.tv_usec + uTimeoutValue * 1000L ) % 1000000;
983 
984  /** Convert from timeval to timespec */
985  ts.tv_sec = tv.tv_sec;
986  ts.tv_nsec = tv.tv_usec * 1000;
987 
988  __TIMESTAMP(); LOG ("Block for %dms & look for KEY RELEASE\n", uTimeoutValue);
989  ret = pthread_cond_timedwait(&tMutexCond, &tMutexLock, &ts);
990 
991  /** Verify the return code to decide on the key release */
992  if (ret == ETIMEDOUT)
993  {
994  __TIMESTAMP(); LOG ("Key NOT released yet. Ready to post REPEAT keys\n");
995  return false;
996  }
997  else
998  {
999  __TIMESTAMP(); LOG ("Key released..\n");
1000  return true;
1001  }
1002 }
1003 
1004 #ifndef NO_RF4CE
1005 #ifndef USE_UNIFIED_CONTROL_MGR_API_1
1006 #ifdef RF4CE_GENMSO_API
1007 /**
1008  * @brief Thread entry fuction to turn off autobind after XX ms
1009  *
1010  * This function executes when auto bind for RF4CE remotes is initiated, waits 600ms and shuts down the auto binding
1011  *
1012  * @param void pointer (NULL)
1013  *
1014  * @return void pointer (NULL)
1015  */
1016 static void* _Rf4ceAutoBindOffThreadFunc(void *arg)
1017 {
1018  if(Rf4ceAutoBindClock!=0){
1019 
1020  useconds_t usecondsToWait = 600000;
1021 
1022  LOG("sleeping for %d\n", usecondsToWait);
1023  usleep(usecondsToWait);
1024  LOG("OUT OF SLEEP\n");
1025 
1026  Rf4ceAutoBindClock=0;
1027  MSOBusAPI_Packet_t setPacket;
1028 
1029  setPacket.msgId = MSOBusAPI_MsgId_AutoBind_LineOfSight; // 0x0A
1030  setPacket.index = 0;
1031  setPacket.length = 1;
1032  setPacket.msg.CheckStatus = 0; //Set or clear
1033 
1034  int rc = IARM_Bus_Call(IARM_BUS_RFMGR_NAME, IARM_BUS_RFMGR_MsgRequest, (void *)&setPacket, sizeof(setPacket));
1035  if(rc >= 0)
1036  {
1037  LOG("clearing autoBind-LineOfSight successful\n");
1038  }
1039  else if(rc < 0)
1040  {
1041  LOG("failed clearing autoBind-LineOfSight with %d\n",rc);
1042  }
1043  }
1044  return arg;
1045 }
1046 
1047 int getTimeMs(){
1048  struct timeval tm;
1049  gettimeofday(&tm, NULL);
1050  return (tm.tv_sec) * 1000 + (tm.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond
1051 }
1052 #elif defined(RF4CE_API)
1053 /**
1054  * @brief Thread entry fuction to turn off autobind after XX ms
1055  *
1056  * This function executes when auto bind for RF4CE remotes is initiated, waits 250ms and shuts down the auto binding
1057  *
1058  * @param void pointer (NULL)
1059  *
1060  * @return void pointer (NULL)
1061  */
1062 static void* _Rf4ceAutoBindOffThreadFunc(void *arg)
1063 {
1064  if(Rf4ceAutoBindClock!=0){
1065 
1066  useconds_t usecondsToWait = 600000;
1067 
1068  LOG("sleeping for %d\n", usecondsToWait);
1069  usleep(usecondsToWait);
1070  LOG("OUT OF SLEEP\n");
1071 
1072  Rf4ceAutoBindClock=0;
1073  rf4ce_Packet_t setPacket;
1074 
1075  setPacket.msgId = rf4ce_MsgId_AutoBind_LineOfSight; // 0x0A
1076  setPacket.index = 0;
1077  setPacket.length = 1;
1078  setPacket.msg.CheckStatus = 0; //Set or clear
1079 
1080  int rc = IARM_Bus_Call(IARM_BUS_RF4CEMGR_NAME, IARM_BUS_RF4CEMGR_MsgRequest, (void *)&setPacket, sizeof(setPacket));
1081  if(rc >= 0)
1082  {
1083  LOG("clearing autoBind-LineOfSight successful\n");
1084  }
1085  else if(rc < 0)
1086  {
1087  LOG("failed clearing autoBind-LineOfSight with %d\n",rc);
1088  }
1089  }
1090  return arg;
1091 }
1092 
1093 int getTimeMs(){
1094  struct timeval tm;
1095  gettimeofday(&tm, NULL);
1096  return (tm.tv_sec) * 1000 + (tm.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond
1097 }
1098 #elif defined(RF4CE_GPMSO_API)
1099 /**
1100  * @brief Thread entry fuction to turn off autobind after XX ms
1101  *
1102  * This function executes when auto bind for RF4CE remotes is initiated, waits 600ms and shuts down the auto binding
1103  *
1104  * @param void pointer (NULL)
1105  *
1106  * @return void pointer (NULL)
1107  */
1108 static void* _Rf4ceAutoBindOffThreadFunc(void *arg)
1109 {
1110  if(Rf4ceAutoBindClock!=0){
1111 
1112  useconds_t usecondsToWait = 600000;
1113 
1114  LOG("sleeping for %d\n", usecondsToWait);
1115  usleep(usecondsToWait);
1116  LOG("OUT OF SLEEP\n");
1117 
1118  Rf4ceAutoBindClock=0;
1119  gpMSOBusAPI_Packet_t setPacket;
1120 
1121  setPacket.msgId = gpMSOBusAPI_MsgId_AutoBind_LineOfSight; // 0x0A
1122  setPacket.index = 0;
1123  setPacket.length = 1;
1124  setPacket.msg.CheckStatus = 0; //Set or clear
1125 
1126  int rc = IARM_Bus_Call(IARM_BUS_GPMGR_NAME, IARM_BUS_GPMGR_API_MsgRequest, (void *)&setPacket, sizeof(setPacket));
1127  if(rc >= 0)
1128  {
1129  LOG("clearing autoBind-LineOfSight successful\n");
1130  }
1131  else if(rc < 0)
1132  {
1133  LOG("failed clearing autoBind-LineOfSight with %d\n",rc);
1134  }
1135  }
1136  return arg;
1137 }
1138 
1139 int getTimeMs(){
1140  struct timeval tm;
1141  gettimeofday(&tm, NULL);
1142  return (tm.tv_sec) * 1000 + (tm.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond
1143 }
1144 #else
1145 #warning "No RF4CE API defined"
1146 #endif
1147 #endif // USE_UNIFIED_CONTROL_MGR_API_1
1148 #endif // NO_RF4CE
1149 
1150 
1151 static void* _LASTKeyTimerThreadFunc(void *arg)
1152 {
1153 #ifdef XMP_TAG_OWNER_SUPPORT
1155 #endif
1156  int i;
1157  useconds_t usecondsToWait = 50000;
1158  bool bSendExitKey = true;
1159 
1160  //Set flag that the timer is running
1161  pthread_mutex_lock(&tKeySeqMutex);
1162  bLastTimerRunning = true;
1163  pthread_mutex_unlock(&tKeySeqMutex);
1164 
1165  //Wait for timer to expire or for the LAST keyup
1166  for (i=0; i<((lastKeyNumMSecs*MICROSECS_PER_MILLISEC) / usecondsToWait); i++)
1167  {
1168  usleep(usecondsToWait);
1169 
1170  //If a LAST keyup was received...
1171  if(bLastKeyUpReceived == true)
1172  {
1173  bSendExitKey = false;
1174  break;
1175  }
1176  }
1177 
1178  pthread_mutex_lock(&tKeySeqMutex);
1179 
1180  //Set flag to ignore LAST key up
1181  bIgnoreLastKeyup = true;
1182 
1183  //If we timed out, then send the EXIT keydown and keyup
1184  if(bSendExitKey == true)
1185  {
1186  IARM_Bus_IRMgr_EventData_t eventData;
1187 
1188  // Send Key Down
1189  LOG("Sending EXIT key instead of LAST\n");
1190  eventData.data.irkey.keyType = KET_KEYDOWN;
1191  eventData.data.irkey.keyCode = KED_EXIT;
1192 #ifdef XMP_TAG_OWNER_SUPPORT
1193  eventData.data.irkey.keyTag = irKey->tag;
1194  eventData.data.irkey.keyOwner = irKey->owner;
1195 #else
1196  eventData.data.irkey.keyTag = XMP_TAG_UNDEFINED;
1197  eventData.data.irkey.keyOwner = XMP_OWNER_UNDEFINED;
1198 #endif
1199  eventData.data.irkey.isFP = 0;
1200  eventData.data.irkey.keySrc = (_IRMgr_KeySrc_t)LASTkeySrc;
1201  eventData.data.irkey.keySourceId = gCurrentKeySrcId;
1202  if (udispatcher){
1203  udispatcher(eventData.data.irkey.keyCode, eventData.data.irkey.keyType, eventData.data.irkey.keySrc);
1204  }
1205  IARM_Bus_BroadcastEvent(IARM_BUS_IRMGR_NAME, (IARM_EventId_t) IARM_BUS_IRMGR_EVENT_IRKEY, (void *)&eventData, sizeof(eventData));
1206 
1207  // Send Key UP
1208  eventData.data.irkey.keyType = KET_KEYUP;
1209  if (udispatcher){
1210  udispatcher(eventData.data.irkey.keyCode, eventData.data.irkey.keyType, eventData.data.irkey.keySrc);
1211  }
1212  IARM_Bus_BroadcastEvent(IARM_BUS_IRMGR_NAME, (IARM_EventId_t) IARM_BUS_IRMGR_EVENT_IRKEY, (void *)&eventData, sizeof(eventData));
1213  }
1214 
1215  //Reset flag that the timer is no longer running
1216  bLastTimerRunning = false;
1217  pthread_mutex_unlock(&tKeySeqMutex);
1218  return NULL;
1219 }
1220 
1221 /**
1222  * @brief Thread entry fuction to post Repeat Keys
1223  *
1224  * This functions handles posting a KET_KEYREPEAT with specified timeout
1225  *
1226  * @param void pointer (NULL)
1227  *
1228  * @return void pointer (NULL)
1229  */
1230 static void* _KeyRepeatThreadFunc (void *arg)
1231 {
1232  bool isTimedout = false;
1233 
1234  /** Loop in..! */
1235  while (1)
1236  {
1237  pthread_mutex_lock(&tMutexLock);
1238  /** When the thread starts, it should wait for the signal..
1239  * The signal will be posted by the very first down key
1240  */
1241  if (!isTimedout)
1242  {
1243  __TIMESTAMP(); LOG ("Block unconditionally & look for KEY PRESS\n");
1244  pthread_cond_wait(&tMutexCond, &tMutexLock);
1245 
1246  /**
1247  * At this point of time, the KET_DOWN is received. So wait for 500ms to see
1248  * the is released or not
1249  */
1250  if (isKeyReleased(gInitialWaitTimeout))
1251  {
1252  /**
1253  * When key released within the timeframe of 500ms, no need to post repeat key.
1254  * Just go back and wait for next key press event
1255  */
1256  pthread_mutex_unlock(&tMutexLock);
1257  continue;
1258  }
1259  else
1260  {
1261  /**
1262  * Post atleast one REPEAT key when the timeout is set to zero by the
1263  * UIDev_SetRepeatInterval() by the clients
1264  */
1265 #ifndef XMP_TAG_OWNER_SUPPORT
1266  _IrInputKeyEventHandler (KET_KEYREPEAT, gCurrentKeyCode, IARM_BUS_IRMGR_KEYSRC_IR, gCurrentKeySrcId);
1267 #else
1268  PLAT_irKey_metadata_t irKey = {KET_KEYREPEAT, gCurrentKeyCode, XMP_TAG_COMCAST, XMP_OWNER_NORMAL};
1269  _IrInputKeyEventHandler (&irKey, IARM_BUS_IRMGR_KEYSRC_IR, gCurrentKeySrcId);
1270 #endif
1271  }
1272  }
1273 
1274  /**
1275  * If the Interval is not set do not start the timer for repeat.
1276  * Only one repeat should be posted thats done from the signaling function itself.
1277  */
1278  if (gRepeatKeyInterval != 0)
1279  {
1280  if (isKeyReleased(gRepeatKeyInterval))
1281  {
1282  isTimedout = false;
1283  __TIMESTAMP(); LOG ("Key pressed.. Do not post Repeat key...\n");
1284  }
1285  else
1286  {
1287  if (KED_UNDEFINEDKEY != gCurrentKeyCode)
1288  {
1289  isTimedout = true;
1290 
1291  //If the last key was RF...
1292  if( bNeedRFKeyUp )
1293  {
1294  numKeyRepeats++;
1295 
1296  //More than 6 repeats means that we lost connection to rf4ceMgr
1297  // numKeyRepeats also gets reset to 0 in the RF event handler
1298  // so the key repeat code will get executed
1299  if(numKeyRepeats > MAX_KEY_REPEATS)
1300  {
1301  __TIMESTAMP(); LOG ("******** Lost connection to rf4ceMgr. Sending Up key...\n");
1302 #ifndef XMP_TAG_OWNER_SUPPORT
1303  _IrInputKeyEventHandler(KET_KEYUP, gCurrentKeyCode, IARM_BUS_IRMGR_KEYSRC_IR, gCurrentKeySrcId);
1304 #else
1305  PLAT_irKey_metadata_t irKey = {KET_KEYUP, gCurrentKeyCode, XMP_TAG_COMCAST, XMP_OWNER_NORMAL};
1306  _IrInputKeyEventHandler(&irKey, IARM_BUS_IRMGR_KEYSRC_IR, gCurrentKeySrcId);
1307 #endif
1308  gCurrentKeyCode = KED_UNDEFINEDKEY;
1309  numKeyRepeats = 0;
1310  bNeedRFKeyUp = false;
1311  }
1312  //Else send a repeat
1313  else
1314  {
1315  __TIMESTAMP(); LOG ("Post Repeat RF key...\n");
1316 #ifndef XMP_TAG_OWNER_SUPPORT
1317  _IrInputKeyEventHandler(KET_KEYREPEAT, gCurrentKeyCode,IARM_BUS_IRMGR_KEYSRC_RF, gCurrentKeySrcId);
1318 #else
1319  PLAT_irKey_metadata_t irKey = {KET_KEYREPEAT, gCurrentKeyCode, XMP_TAG_COMCAST, XMP_OWNER_NORMAL};
1320  _IrInputKeyEventHandler(&irKey, IARM_BUS_IRMGR_KEYSRC_RF, gCurrentKeySrcId);
1321 #endif
1322  }
1323  }
1324  //Else this is IR
1325  else
1326  {
1327  __TIMESTAMP(); LOG ("Post Repeat key...\n");
1328 #ifndef XMP_TAG_OWNER_SUPPORT
1329  _IrInputKeyEventHandler(KET_KEYREPEAT, gCurrentKeyCode,IARM_BUS_IRMGR_KEYSRC_IR, gCurrentKeySrcId);
1330 #else
1331  PLAT_irKey_metadata_t irKey = {KET_KEYREPEAT, gCurrentKeyCode, XMP_TAG_COMCAST, XMP_OWNER_NORMAL};
1332  _IrInputKeyEventHandler(&irKey, IARM_BUS_IRMGR_KEYSRC_IR, gCurrentKeySrcId);
1333 #endif
1334  }
1335  }
1336  else
1337  {
1338  isTimedout = false;
1339  }
1340  }
1341  }
1342  pthread_mutex_unlock(&tMutexLock);
1343  }
1344 
1345  return arg;
1346 }
1347 
1348 /**
1349  * @brief Event Handler for RF Key Events
1350  *
1351  * This function is a Event handler for RF key events. Post the Key to IARM IR key handler.
1352  *
1353  * @param void pointer (Event ID , Data and Length)
1354  *
1355  * @return void pointer (NULL)
1356  */
1357 #ifndef NO_RF4CE
1358 #ifdef USE_UNIFIED_CONTROL_MGR_API_1
1359 static void _ctrlmEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
1360 {
1361  int keyCode = 0;
1362  int keyType = 0;
1363  unsigned int remoteId = 0;
1364 
1365  if (eventId == CTRLM_RCU_IARM_EVENT_KEY_PRESS) {
1366  ctrlm_rcu_iarm_event_key_press_t* keyEvent = (ctrlm_rcu_iarm_event_key_press_t*)data;
1367  if (keyEvent != NULL) {
1368  if (keyEvent->api_revision != CTRLM_RCU_IARM_BUS_API_REVISION) {
1369  LOG("CTRLM key event: ERROR - Wrong CTRLM API revision - expected %d, event is %d!!",
1370  CTRLM_RCU_IARM_BUS_API_REVISION, keyEvent->api_revision);
1371  return;
1372  }
1373 
1374  if(0 != keyLogStatus)
1375  {
1376  LOG("CTRLM key event: network_id: %d, network_type: %d, controller_id: %d, key_status: %d, key_code: 0x%02X.\n",
1377  keyEvent->network_id, keyEvent->network_type, keyEvent->controller_id, keyEvent->key_status, keyEvent->key_code);
1378  }
1379 
1380  if (keyEvent->key_status != CTRLM_KEY_STATUS_INVALID) {
1381  remoteId = keyEvent->controller_id;
1382  // Translate CTRLM key status into Comcast RDK key types
1383  switch (keyEvent->key_status) {
1384  case CTRLM_KEY_STATUS_DOWN: keyType = KET_KEYDOWN; break;
1385  case CTRLM_KEY_STATUS_UP: keyType = KET_KEYUP; break;
1386  case CTRLM_KEY_STATUS_REPEAT: keyType = KET_KEYREPEAT; break;
1387  }
1388  // Translate CTRLM key codes into Comcast RDK key codes
1389  switch (keyEvent->key_code) {
1390  case CTRLM_KEY_CODE_OK: keyCode = KED_SELECT; break;
1391 
1392  case CTRLM_KEY_CODE_UP_ARROW: keyCode = KED_ARROWUP; break;
1393  case CTRLM_KEY_CODE_DOWN_ARROW: keyCode = KED_ARROWDOWN; break;
1394  case CTRLM_KEY_CODE_LEFT_ARROW: keyCode = KED_ARROWLEFT; break;
1395  case CTRLM_KEY_CODE_RIGHT_ARROW: keyCode = KED_ARROWRIGHT; break;
1396 
1397  case CTRLM_KEY_CODE_MENU: keyCode = KED_MENU; break;
1398  case CTRLM_KEY_CODE_DVR: keyCode = KED_MYDVR; break;
1399  case CTRLM_KEY_CODE_FAV: keyCode = KED_FAVORITE; break;
1400  case CTRLM_KEY_CODE_EXIT: keyCode = KED_EXIT; break;
1401 // case CTRLM_KEY_CODE_HOME: keyCode = KED_????; break;
1402 
1403  case CTRLM_KEY_CODE_DIGIT_0: keyCode = KED_DIGIT0; break;
1404  case CTRLM_KEY_CODE_DIGIT_1: keyCode = KED_DIGIT1; break;
1405  case CTRLM_KEY_CODE_DIGIT_2: keyCode = KED_DIGIT2; break;
1406  case CTRLM_KEY_CODE_DIGIT_3: keyCode = KED_DIGIT3; break;
1407  case CTRLM_KEY_CODE_DIGIT_4: keyCode = KED_DIGIT4; break;
1408  case CTRLM_KEY_CODE_DIGIT_5: keyCode = KED_DIGIT5; break;
1409  case CTRLM_KEY_CODE_DIGIT_6: keyCode = KED_DIGIT6; break;
1410  case CTRLM_KEY_CODE_DIGIT_7: keyCode = KED_DIGIT7; break;
1411  case CTRLM_KEY_CODE_DIGIT_8: keyCode = KED_DIGIT8; break;
1412  case CTRLM_KEY_CODE_DIGIT_9: keyCode = KED_DIGIT9; break;
1413  case CTRLM_KEY_CODE_PERIOD: keyCode = KED_PERIOD; break;
1414 
1415  case CTRLM_KEY_CODE_RETURN: keyCode = KED_ENTER; break;
1416  case CTRLM_KEY_CODE_CH_UP: keyCode = KED_CHANNELUP; break;
1417  case CTRLM_KEY_CODE_CH_DOWN: keyCode = KED_CHANNELDOWN; break;
1418  case CTRLM_KEY_CODE_LAST: keyCode = KED_LAST; break;
1419  case CTRLM_KEY_CODE_LANG: keyCode = KED_LANGUAGE; break;
1420  case CTRLM_KEY_CODE_INPUT_SELECT: keyCode = KED_INPUTKEY; break;
1421  case CTRLM_KEY_CODE_INFO: keyCode = KED_INFO; break;
1422  case CTRLM_KEY_CODE_HELP: keyCode = KED_HELP; break;
1423  case CTRLM_KEY_CODE_PAGE_UP: keyCode = KED_PAGEUP; break;
1424  case CTRLM_KEY_CODE_PAGE_DOWN: keyCode = KED_PAGEDOWN; break;
1425 // case CTRLM_KEY_CODE_MOTION: keyCode = KED_????; break;
1426  case CTRLM_KEY_CODE_SEARCH: keyCode = KED_SEARCH; break;
1427  case CTRLM_KEY_CODE_LIVE: keyCode = KED_LIVE; break;
1428 // case CTRLM_KEY_CODE_HD_ZOOM: keyCode = KED_????; break;
1429 // case CTRLM_KEY_CODE_SHARE: keyCode = KED_????; break;
1430 
1431  case CTRLM_KEY_CODE_TV_POWER: keyCode = KED_TVPOWER; break;
1432  case CTRLM_KEY_CODE_VOL_UP: keyCode = KED_VOLUMEUP; break;
1433  case CTRLM_KEY_CODE_VOL_DOWN: keyCode = KED_VOLUMEDOWN; break;
1434  case CTRLM_KEY_CODE_MUTE: keyCode = KED_MUTE; break;
1435  case CTRLM_KEY_CODE_PLAY: keyCode = KED_PLAY; break;
1436  case CTRLM_KEY_CODE_STOP: keyCode = KED_STOP; break;
1437  case CTRLM_KEY_CODE_PAUSE: keyCode = KED_PAUSE; break;
1438  case CTRLM_KEY_CODE_RECORD: keyCode = KED_RECORD; break;
1439  case CTRLM_KEY_CODE_REWIND: keyCode = KED_REWIND; break;
1440  case CTRLM_KEY_CODE_FAST_FORWARD: keyCode = KED_FASTFORWARD; break;
1441 // case CTRLM_KEY_CODE_30_SEC_SKIP: keyCode = KED_????; break;
1442  case CTRLM_KEY_CODE_REPLAY: keyCode = KED_REPLAY; break;
1443 
1444  case CTRLM_KEY_CODE_SWAP: keyCode = KED_DISPLAY_SWAP; break; // Swap display, or channel?
1445  case CTRLM_KEY_CODE_ON_DEMAND: keyCode = KED_ONDEMAND; break;
1446  case CTRLM_KEY_CODE_GUIDE: keyCode = KED_GUIDE; break;
1447  case CTRLM_KEY_CODE_PUSH_TO_TALK: keyCode = KED_PUSH_TO_TALK; break;
1448 
1449  case CTRLM_KEY_CODE_PIP_ON_OFF: keyCode = KED_PINP_TOGGLE; break;
1450  case CTRLM_KEY_CODE_PIP_MOVE: keyCode = KED_PINP_MOVE; break;
1451  case CTRLM_KEY_CODE_PIP_CH_UP: keyCode = KED_PINP_CHUP; break;
1452  case CTRLM_KEY_CODE_PIP_CH_DOWN: keyCode = KED_PINP_CHDOWN; break;
1453 
1454 // case CTRLM_KEY_CODE_LOCK: keyCode = KED_????; break;
1455 // case CTRLM_KEY_CODE_DAY_PLUS: keyCode = KED_????; break;
1456 // case CTRLM_KEY_CODE_DAY_MINUS: keyCode = KED_????; break;
1457  case CTRLM_KEY_CODE_PLAY_PAUSE: keyCode = KED_PLAY; break;
1458 // case CTRLM_KEY_CODE_STOP_VIDEO: keyCode = KED_????; break;
1459 // case CTRLM_KEY_CODE_MUTE_MIC: keyCode = KED_????; break;
1460 
1461  case CTRLM_KEY_CODE_POWER_TOGGLE: keyCode = KED_RF_POWER; break;
1462  case CTRLM_KEY_CODE_POWER_OFF: keyCode = KED_DISCRETE_POWER_STANDBY; break;
1463  case CTRLM_KEY_CODE_POWER_ON: keyCode = KED_DISCRETE_POWER_ON; break;
1464 
1465  case CTRLM_KEY_CODE_OCAP_B: keyCode = KED_KEYB; break;
1466  case CTRLM_KEY_CODE_OCAP_C: keyCode = KED_KEYC; break;
1467  case CTRLM_KEY_CODE_OCAP_D: keyCode = KED_KEYD; break;
1468  case CTRLM_KEY_CODE_OCAP_A: keyCode = KED_KEYA; break;
1469 
1470  case CTRLM_KEY_CODE_CC: keyCode = KED_CLOSED_CAPTIONING; break;
1471 // case CTRLM_KEY_CODE_PROFILE: keyCode = KED_????; break;
1472 // case CTRLM_KEY_CODE_CALL: keyCode = KED_????; break;
1473 // case CTRLM_KEY_CODE_HOLD: keyCode = KED_????; break;
1474 // case CTRLM_KEY_CODE_END: keyCode = KED_????; break;
1475 // case CTRLM_KEY_CODE_VIEWS: keyCode = KED_????; break;
1476 // case CTRLM_KEY_CODE_SELF_VIEW: keyCode = KED_????; break;
1477 // case CTRLM_KEY_CODE_ZOOM_IN: keyCode = KED_????; break;
1478 // case CTRLM_KEY_CODE_ZOOM_OUT: keyCode = KED_????; break;
1479  case CTRLM_KEY_CODE_BACKSPACE: keyCode = KED_DELETE; break;
1480 // case CTRLM_KEY_CODE_LOCK_UNLOCK: keyCode = KED_????; break;
1481 // case CTRLM_KEY_CODE_CAPS: keyCode = KED_????; break;
1482 // case CTRLM_KEY_CODE_ALT: keyCode = KED_????; break;
1483 // case CTRLM_KEY_CODE_SPACE: keyCode = KED_????; break;
1484 // case CTRLM_KEY_CODE_WWW_DOT: keyCode = KED_????; break;
1485 // case CTRLM_KEY_CODE_DOT_COM: keyCode = KED_????; break;
1486 
1487 // case CTRLM_KEY_CODE_UPPER_A: keyCode = KED_????; break;
1488 // case CTRLM_KEY_CODE_UPPER_B: keyCode = KED_????; break;
1489 // case CTRLM_KEY_CODE_UPPER_C: keyCode = KED_????; break;
1490 // case CTRLM_KEY_CODE_UPPER_D: keyCode = KED_????; break;
1491 // case CTRLM_KEY_CODE_UPPER_E: keyCode = KED_????; break;
1492 // case CTRLM_KEY_CODE_UPPER_F: keyCode = KED_????; break;
1493 // case CTRLM_KEY_CODE_UPPER_G: keyCode = KED_????; break;
1494 // case CTRLM_KEY_CODE_UPPER_H: keyCode = KED_????; break;
1495 // case CTRLM_KEY_CODE_UPPER_I: keyCode = KED_????; break;
1496 // case CTRLM_KEY_CODE_UPPER_J: keyCode = KED_????; break;
1497 // case CTRLM_KEY_CODE_UPPER_K: keyCode = KED_????; break;
1498 // case CTRLM_KEY_CODE_UPPER_L: keyCode = KED_????; break;
1499 // case CTRLM_KEY_CODE_UPPER_M: keyCode = KED_????; break;
1500 // case CTRLM_KEY_CODE_UPPER_N: keyCode = KED_????; break;
1501 // case CTRLM_KEY_CODE_UPPER_O: keyCode = KED_????; break;
1502 // case CTRLM_KEY_CODE_UPPER_P: keyCode = KED_????; break;
1503 // case CTRLM_KEY_CODE_UPPER_Q: keyCode = KED_????; break;
1504 // case CTRLM_KEY_CODE_UPPER_R: keyCode = KED_????; break;
1505 // case CTRLM_KEY_CODE_UPPER_S: keyCode = KED_????; break;
1506 // case CTRLM_KEY_CODE_UPPER_T: keyCode = KED_????; break;
1507 // case CTRLM_KEY_CODE_UPPER_U: keyCode = KED_????; break;
1508 // case CTRLM_KEY_CODE_UPPER_V: keyCode = KED_????; break;
1509 // case CTRLM_KEY_CODE_UPPER_W: keyCode = KED_????; break;
1510 // case CTRLM_KEY_CODE_UPPER_X: keyCode = KED_????; break;
1511 // case CTRLM_KEY_CODE_UPPER_Y: keyCode = KED_????; break;
1512 // case CTRLM_KEY_CODE_UPPER_Z: keyCode = KED_????; break;
1513 
1514 // case CTRLM_KEY_CODE_LOWER_A: keyCode = KED_????; break;
1515 // case CTRLM_KEY_CODE_LOWER_B: keyCode = KED_????; break;
1516 // case CTRLM_KEY_CODE_LOWER_C: keyCode = KED_????; break;
1517 // case CTRLM_KEY_CODE_LOWER_D: keyCode = KED_????; break;
1518 // case CTRLM_KEY_CODE_LOWER_E: keyCode = KED_????; break;
1519 // case CTRLM_KEY_CODE_LOWER_F: keyCode = KED_????; break;
1520 // case CTRLM_KEY_CODE_LOWER_G: keyCode = KED_????; break;
1521 // case CTRLM_KEY_CODE_LOWER_H: keyCode = KED_????; break;
1522 // case CTRLM_KEY_CODE_LOWER_I: keyCode = KED_????; break;
1523 // case CTRLM_KEY_CODE_LOWER_J: keyCode = KED_????; break;
1524 // case CTRLM_KEY_CODE_LOWER_K: keyCode = KED_????; break;
1525 // case CTRLM_KEY_CODE_LOWER_L: keyCode = KED_????; break;
1526 // case CTRLM_KEY_CODE_LOWER_M: keyCode = KED_????; break;
1527 // case CTRLM_KEY_CODE_LOWER_N: keyCode = KED_????; break;
1528 // case CTRLM_KEY_CODE_LOWER_O: keyCode = KED_????; break;
1529 // case CTRLM_KEY_CODE_LOWER_P: keyCode = KED_????; break;
1530 // case CTRLM_KEY_CODE_LOWER_Q: keyCode = KED_????; break;
1531 // case CTRLM_KEY_CODE_LOWER_R: keyCode = KED_????; break;
1532 // case CTRLM_KEY_CODE_LOWER_S: keyCode = KED_????; break;
1533 // case CTRLM_KEY_CODE_LOWER_T: keyCode = KED_????; break;
1534 // case CTRLM_KEY_CODE_LOWER_U: keyCode = KED_????; break;
1535 // case CTRLM_KEY_CODE_LOWER_V: keyCode = KED_????; break;
1536 // case CTRLM_KEY_CODE_LOWER_W: keyCode = KED_????; break;
1537 // case CTRLM_KEY_CODE_LOWER_X: keyCode = KED_????; break;
1538 // case CTRLM_KEY_CODE_LOWER_Y: keyCode = KED_????; break;
1539 // case CTRLM_KEY_CODE_LOWER_Z: keyCode = KED_????; break;
1540 
1541 // case CTRLM_KEY_CODE_QUESTION: keyCode = KED_????; break;
1542 // case CTRLM_KEY_CODE_EXCLAMATION: keyCode = KED_????; break;
1543  case CTRLM_KEY_CODE_POUND: keyCode = KED_POUND; break;
1544 // case CTRLM_KEY_CODE_DOLLAR: keyCode = KED_????; break;
1545 // case CTRLM_KEY_CODE_PERCENT: keyCode = KED_????; break;
1546 // case CTRLM_KEY_CODE_AMPERSAND: keyCode = KED_????; break;
1547  case CTRLM_KEY_CODE_ASTERISK: keyCode = KED_PROGRAM; break;
1548 // case CTRLM_KEY_CODE_LEFT_PAREN: keyCode = KED_????; break;
1549 // case CTRLM_KEY_CODE_RIGHT_PAREN: keyCode = KED_????; break;
1550 // case CTRLM_KEY_CODE_PLUS: keyCode = KED_????; break;
1551 // case CTRLM_KEY_CODE_MINUS: keyCode = KED_????; break;
1552 // case CTRLM_KEY_CODE_EQUAL: keyCode = KED_????; break;
1553 // case CTRLM_KEY_CODE_FORWARD_SLASH: keyCode = KED_????; break;
1554 // case CTRLM_KEY_CODE_UNDERSCORE: keyCode = KED_????; break;
1555 // case CTRLM_KEY_CODE_DOUBLE_QUOTE: keyCode = KED_????; break;
1556 // case CTRLM_KEY_CODE_COLON: keyCode = KED_????; break;
1557 // case CTRLM_KEY_CODE_SEMICOLON: keyCode = KED_????; break;
1558 // case CTRLM_KEY_CODE_COMMERCIAL_AT: keyCode = KED_????; break;
1559 // case CTRLM_KEY_CODE_APOSTROPHE: keyCode = KED_????; break;
1560 // case CTRLM_KEY_CODE_COMMA: keyCode = KED_????; break;
1561  case CTRLM_KEY_CODE_INVALID: keyCode = KED_UNDEFINEDKEY; break;
1562 
1563  default: keyCode = KED_UNDEFINEDKEY; break;
1564  }
1565  } else {
1566  LOG("CTRLM key event: ERROR: INVALID key status!!\n");
1567  return;
1568  }
1569  } else {
1570  LOG("CTRLM key event: ERROR: NULL event data!!\n");
1571  return;
1572  }
1573  } else if (eventId == CTRLM_RCU_IARM_EVENT_KEY_GHOST) {
1574  ctrlm_rcu_iarm_event_key_ghost_t* ghostEvent = (ctrlm_rcu_iarm_event_key_ghost_t*)data;
1575  if (ghostEvent != NULL) {
1576  if (ghostEvent->api_revision != CTRLM_RCU_IARM_BUS_API_REVISION) {
1577  LOG("CTRLM ghost key event: ERROR - Wrong CTRLM API revision - expected %d, event is %d!!",
1578  CTRLM_RCU_IARM_BUS_API_REVISION, ghostEvent->api_revision);
1579  return;
1580  }
1581  LOG("CTRLM ghost code event: network_id: %d, network_type: %d, controller_id: %d, ghost_code: %d.\n",
1582  ghostEvent->network_id, ghostEvent->network_type, ghostEvent->controller_id, ghostEvent->ghost_code);
1583  // Translate the ghost code into a fake keystroke
1584  remoteId = ghostEvent->controller_id;
1585  switch (ghostEvent->ghost_code) {
1586  case CTRLM_RCU_GHOST_CODE_VOLUME_UNITY_GAIN:
1587  keyType = KET_KEYDOWN;
1588  keyCode = KED_VOLUME_OPTIMIZE;
1589  break;
1590  // We don't translate the power ghost codes to fake keystrokes.
1591  default:
1592  // Do nothing
1593  return;
1594  }
1595  } else {
1596  LOG("CTRLM ghost code event: ERROR: NULL event data!!\n");
1597  return;
1598  }
1599  } else if (eventId == CTRLM_RCU_IARM_EVENT_FUNCTION) {
1600  ctrlm_rcu_iarm_event_function_t* functionEvent = (ctrlm_rcu_iarm_event_function_t*)data;
1601  if (functionEvent != NULL) {
1602  if (functionEvent->api_revision != CTRLM_RCU_IARM_BUS_API_REVISION) {
1603  LOG("CTRLM function event: ERROR - Wrong CTRLM API revision - expected %d, event is %d!!",
1604  CTRLM_RCU_IARM_BUS_API_REVISION, functionEvent->api_revision);
1605  return;
1606  }
1607  LOG("CTRLM rcu function event: network_id: %d, network_type: %d, controller_id: %d, function: %d, value: 0x%08X.\n",
1608  functionEvent->network_id, functionEvent->network_type, functionEvent->controller_id, functionEvent->function, functionEvent->value);
1609  // We're not generating a fake keystroke for the SETUP function event, or any other, right now.
1610  return;
1611  } else {
1612  LOG("CTRLM rcu function event: ERROR: NULL event data!!\n");
1613  return;
1614  }
1615  } else {
1616  LOG("CTRLM key event: ERROR: bad event type %d!!\n", eventId);
1617  return;
1618  }
1619  /*
1620  * The key code should not driver the Power standby
1621  * It shall behave like normal Remote All Power Key
1622  * Fix to XONE-10023
1623  */
1624  if (keyCode == KED_POWER)
1625  {
1626  keyCode = KED_RF_POWER;
1627  }
1628 
1629  //Reset number of key repeats
1630  numKeyRepeats = 0;
1631 
1632  //If key up then we don't need artificially send a key up if rf4ceMgr crashes
1633  if( keyType == KET_KEYUP )
1634  bNeedRFKeyUp = false;
1635  else
1636  bNeedRFKeyUp = true;
1637 
1638 #ifndef XMP_TAG_OWNER_SUPPORT
1639  _IrKeyCallbackFrom(keyType, keyCode, IARM_BUS_IRMGR_KEYSRC_RF, remoteId);
1640 #else
1641  PLAT_irKey_metadata_t irKey = {keyType, keyCode, XMP_TAG_COMCAST, XMP_OWNER_NORMAL};
1642  _IrKeyCallbackFrom(&irKey, IARM_BUS_IRMGR_KEYSRC_RF, remoteId);
1643 #endif
1644 
1645 }
1646 #else
1647 #ifdef RF4CE_GENMSO_API
1648 static void _rfEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
1649 {
1650  LOG("BusTestApplication: %d> UserControlIndication 0x%lx\n",((MSOBusAPI_Packet_t*)data)->msg.UserCommand.remoteId,
1651  ((MSOBusAPI_Packet_t*)data)->msg.UserCommand.keyStatus);
1652 
1653  int keyCode = ((MSOBusAPI_Packet_t*)data)->msg.UserCommand.commandCode;
1654  int keyType = ((MSOBusAPI_Packet_t*)data)->msg.UserCommand.keyStatus;
1655  unsigned char remoteId = ((MSOBusAPI_UserCommand_t*)data)->remoteId;
1656 
1657  /*
1658  * The key code from RF should not driver the Power standby
1659  * It shall behave like normal Remote All Power Key
1660  * Fix to XONE-10023
1661  */
1662  if (keyCode == KED_POWER)
1663  {
1664  keyCode = KED_RF_POWER;
1665  }
1666 
1667  //Reset number of key repeats
1668  numKeyRepeats = 0;
1669 
1670  //If key up then we don't need artificially send a key up if rf4ceMgr crashes
1671  if( keyType == KET_KEYUP )
1672  bNeedRFKeyUp = false;
1673  else
1674  bNeedRFKeyUp = true;
1675 
1676 #ifndef XMP_TAG_OWNER_SUPPORT
1677  _IrKeyCallbackFrom(keyType, keyCode, IARM_BUS_IRMGR_KEYSRC_RF, remoteId);
1678 #else
1679  PLAT_irKey_metadata_t irKey = {keyType, keyCode, XMP_TAG_COMCAST, XMP_OWNER_NORMAL};
1680  _IrKeyCallbackFrom(&irKey, IARM_BUS_IRMGR_KEYSRC_RF, remoteId);
1681 #endif
1682 }
1683 #elif defined(RF4CE_API)
1684 static void _rf4ceEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
1685 {
1686 
1687  LOG("BusTestApplication: %d> UserControlIndication 0x%lx\n",((rf4ce_UserCommand_t*)data)->remoteId,
1688  ((rf4ce_UserCommand_t*)data)->keyStatus);
1689 
1690  int keyCode = ((rf4ce_UserCommand_t*)data)->commandCode;
1691  int keyType = ((rf4ce_UserCommand_t*)data)->keyStatus;
1692  unsigned int remoteId = ((rf4ce_UserCommand_t*)data)->remoteId;
1693 
1694  /*
1695  * The key code should not driver the Power standby
1696  * It shall behave like normal Remote All Power Key
1697  * Fix to XONE-10023
1698  */
1699  if (keyCode == KED_POWER)
1700  {
1701  keyCode = KED_RF_POWER;
1702  }
1703 
1704  //Reset number of key repeats
1705  numKeyRepeats = 0;
1706 
1707  //If key up then we don't need artificially send a key up if rf4ceMgr crashes
1708  if( keyType == KET_KEYUP )
1709  bNeedRFKeyUp = false;
1710  else
1711  bNeedRFKeyUp = true;
1712 
1713 #ifndef XMP_TAG_OWNER_SUPPORT
1714  _IrKeyCallbackFrom(keyType, keyCode, IARM_BUS_IRMGR_KEYSRC_RF, remoteId);
1715 #else
1716  PLAT_irKey_metadata_t irKey = {keyType, keyCode, XMP_TAG_COMCAST, XMP_OWNER_NORMAL};
1717  _IrKeyCallbackFrom(&irKey, IARM_BUS_IRMGR_KEYSRC_RF, remoteId);
1718 #endif
1719 
1720 }
1721 #elif defined(RF4CE_GPMSO_API)
1722 static void _gpEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
1723 {
1724 
1725  LOG("BusTestApplication: %d> UserControlIndication 0x%lx\n",((gpMSOBusAPI_UserCommand_t*)data)->remoteId,
1726  ((gpMSOBusAPI_UserCommand_t*)data)->keyStatus);
1727 
1728  int keyCode = ((gpMSOBusAPI_UserCommand_t*)data)->commandCode;//from IARM_Bus_GpMgr_EventData_t
1729  int keyType = ((gpMSOBusAPI_UserCommand_t*)data)->keyStatus;//from IARM_Bus_GpMgr_EventData_t
1730  unsigned char remoteId = ((gpMSOBusAPI_UserCommand_t*)data)->remoteId;
1731 
1732  /*
1733  * The key code from Green Peak should not driver the Power standby
1734  * It shall behave like normal Remote All Power Key
1735  * Fix to XONE-10023
1736  */
1737  if (keyCode == KED_POWER)
1738  {
1739  keyCode = KED_RF_POWER;
1740  }
1741 
1742  //Reset number of key repeats
1743  numKeyRepeats = 0;
1744 
1745  //If key up then we don't need artificially send a key up if rf4ceMgr crashes
1746  if( keyType == KET_KEYUP )
1747  bNeedRFKeyUp = false;
1748  else
1749  bNeedRFKeyUp = true;
1750 
1751 #ifndef XMP_TAG_OWNER_SUPPORT
1752  _IrKeyCallbackFrom(keyType, keyCode, IARM_BUS_IRMGR_KEYSRC_RF, remoteId);
1753 #else
1754  PLAT_irKey_metadata_t irKey = {keyType, keyCode, XMP_TAG_COMCAST, XMP_OWNER_NORMAL};
1755  _IrKeyCallbackFrom(&irKey, IARM_BUS_IRMGR_KEYSRC_RF, remoteId);
1756 #endif
1757 
1758 }
1759 #else
1760 #warning "No RF4CE API defined"
1761 #endif
1762 #endif // USE_UNIFIED_CONTROL_MGR_API_1
1763 #endif // NO_RF4CE
1764 
1765 
1766 
1767 
1768 
1769 static void _logEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
1770 {
1771  unsigned long messageLength=0;
1772  if ((strcmp(owner, IARM_BUS_SYSMGR_NAME) == 0) && (eventId == IARM_BUS_SYSMGR_EVENT_KEYCODE_LOGGING_CHANGED)) {
1774  LOG("Received Keycodelogging event with log status: %d \n", eventData->data.keyCodeLogData.logStatus);
1775  keyLogStatus = eventData->data.keyCodeLogData.logStatus;
1776  }
1777 }
1778 /** @} */
1779 /** @} */
_IARM_BUS_SYSMGR_KEYCodeLoggingInfo_Param_t
Definition: sysMgr.h:123
IARM_Bus_IRMgr_KeySrc_t
enum _IRMgr_KeySrc_t IARM_Bus_IRMgr_KeySrc_t
PLAT_irKey_metadata::tag
PLAT_xmp_tag_t tag
Designates which device key belongs.
Definition: plat_ir.h:68
IRMgr_Register_uinput
IARM_Result_t IRMgr_Register_uinput(uinput_dispatcher_t f)
register a uinput dispatcher.
Definition: irMgr.c:145
IARM_Bus_Term
IARM_Result_t IARM_Bus_Term(void)
This API is used to terminate the IARM-Bus library.
PLAT_API_LOOP
void PLAT_API_LOOP()
This function executes the key event loop.
PLAT_irKey_metadata::code
int code
Code of the pressed key (left, right, power, etc)
Definition: plat_ir.h:67
IARM_BUS_IRMGR_EVENT_IRKEY
@ IARM_BUS_IRMGR_EVENT_IRKEY
Definition: irMgr.h:220
sysMgr.h
IARM-Bus Sys Manager Public API.
IRMgr_Start
IARM_Result_t IRMgr_Start(int argc, char *argv[])
Starts the IR manager.
Definition: irMgr.c:151
PLAT_irKey_metadata
IR Key struct that maintains meta data.
Definition: plat_ir.h:65
IARM_BUS_IRMGR_KEYSRC_RF
@ IARM_BUS_IRMGR_KEYSRC_RF
Definition: irMgr.h:230
IARM_BUS_SYSMGR_NAME
#define IARM_BUS_SYSMGR_NAME
Definition: sysMgr.h:110
PLAT_API_TERM
void PLAT_API_TERM(void)
This API is used to terminate the IR device module.
IRMgr_Stop
IARM_Result_t IRMgr_Stop(void)
Terminates the IR manager.
Definition: irMgr.c:235
_IARM_Bus_IRMgr_GetRepeatInterval_Param_t
Definition: irMgr.h:264
irMgrInternal.h
IARM-Bus IR Manager Internal API.
PLAT_irKey_metadata::owner
PLAT_xmp_owner_t owner
Designates how key should be handled.
Definition: plat_ir.h:69
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
IARM_BUS_IRMGR_EVENT_MAX
@ IARM_BUS_IRMGR_EVENT_MAX
Definition: irMgr.h:222
manager.hpp
It contains class referenced by manager.cpp file.
PLAT_API_RegisterIRKeyCallback
void PLAT_API_RegisterIRKeyCallback(PLAT_IrKeyCallback_t func)
This API must registers a callback function to which IR Key events should be posted.
IARM_BUS_IRMGR_KEYSRC_FP
@ IARM_BUS_IRMGR_KEYSRC_FP
Definition: irMgr.h:228
_IARM_Bus_IRMgr_SetRepeatInterval_Param_t
Definition: irMgr.h:256
PLAT_API_RegisterIRKeyCallbackExtended
void PLAT_API_RegisterIRKeyCallbackExtended(PLAT_IrKeyCallback_Extended_t func)
This API must registers a callback function to which IR Key events should be posted.
IARM_Bus_RegisterEvent
IARM_Result_t IARM_Bus_RegisterEvent(IARM_EventId_t maxEventId)
This API is used to register all the events that are published by the application.
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
IARM_Bus_RegisterCall
IARM_Result_t IARM_Bus_RegisterCall(const char *methodName, IARM_BusCall_t handler)
This API is used to register an RPC method that can be invoked by other applications.
IARM_Bus_RemoveEventHandler
IARM_Result_t IARM_Bus_RemoveEventHandler(const char *ownerName, IARM_EventId_t eventId, IARM_EventHandler_t handler)
Remove specific handler registered for the given event.
Definition: iarmMgrMocks.cpp:50
IARM_BUS_IRMGR_API_GetRepeatInterval
#define IARM_BUS_IRMGR_API_GetRepeatInterval
Definition: irMgr.h:261
IARM_Bus_Disconnect
IARM_Result_t IARM_Bus_Disconnect(void)
This API disconnect Application from IARM Bus so the application will not receive any IARM event or R...
IARMCEC_SendCECActiveSource
bool IARMCEC_SendCECActiveSource(bool bCecLocalLogic, int keyType, int keyCode)
Utility function to send ActiveSource CEC event to TV.
Definition: iarmcec.c:29
_IARM_BUS_SYSMgr_EventData_t
Definition: sysMgr.h:229
device::Manager::Initialize
static void Initialize()
This API is used to initialize the Device Setting module. Each API should be called by any client of ...
Definition: manager.cpp:97
_IrInputKeyEventHandler
static void _IrInputKeyEventHandler(int keyType, int keyCode, int keySrc, unsigned int keySrcId)
Calback funtion to that is registered with MAF to get notified for the key press.
Definition: irMgr.c:494
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...
libIBus.h
RDK IARM-Bus API Declarations.
IARM_BUS_IRMGR_NAME
#define IARM_BUS_IRMGR_NAME
Definition: irMgr.h:216
_IARM_Bus_IRMgr_GetRepeatInterval_Param_t::timeout
unsigned int timeout
Definition: irMgr.h:265
PLAT_API_INIT
int PLAT_API_INIT(void)
This API initializes the underlying IR module.
PLAT_irKey_metadata::type
int type
Event type of key press (up, down, repeat, etc)
Definition: plat_ir.h:66
isKeyReleased
static bool isKeyReleased(unsigned int uTimeoutValue)
Calback funtion to that is registered with MAF to get notified for the key press.
Definition: irMgr.c:972
_IARM_Bus_IRMgr_SetRepeatInterval_Param_t::timeout
unsigned int timeout
Definition: irMgr.h:258
IARM_BUS_IRMGR_KEYSRC_IR
@ IARM_BUS_IRMGR_KEYSRC_IR
Definition: irMgr.h:229
_IRMgr_KeySrc_t
_IRMgr_KeySrc_t
Definition: irMgr.h:227
IRMgr_Loop
IARM_Result_t IRMgr_Loop()
Loop to keep the IR manager alive.
Definition: irMgr.c:221
keyType
Definition: reset.c:85
device::Manager::DeInitialize
static void DeInitialize()
This API is used to deinitialize the device settings module. DeInitialize() must be called to release...
Definition: manager.cpp:138
irMgr.h
IARM-Bus IR Manager API.
_IRMgr_EventData_t
Definition: irMgr.h:235
_SetRepeatInterval
static IARM_Result_t _SetRepeatInterval(void *arg)
Sets key repeat interval.
Definition: irMgr.c:279
IARM_Bus_Connect
IARM_Result_t IARM_Bus_Connect(void)
This API is used to connect application to the IARM bus daemon. After connected, the application can ...
Definition: iarmMgrMocks.cpp:33
_logEventHandler
static void _logEventHandler(const char *owner, IARM_EventId_t eventId, void *data, size_t len)
Event Handler for RF Key Events.
Definition: irMgr.c:1769
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...
IARM_BUS_IRMGR_API_SetRepeatInterval
#define IARM_BUS_IRMGR_API_SetRepeatInterval
Definition: irMgr.h:253
_KeyRepeatThreadFunc
static void * _KeyRepeatThreadFunc(void *arg)
Thread entry fuction to post Repeat Keys.
Definition: irMgr.c:1230
IARM_Bus_Init
IARM_Result_t IARM_Bus_Init(const char *name)
This API is used to initialize the IARM-Bus library.
Definition: iarmMgrMocks.cpp:38
IARM_BUS_SYSMGR_EVENT_KEYCODE_LOGGING_CHANGED
@ IARM_BUS_SYSMGR_EVENT_KEYCODE_LOGGING_CHANGED
Definition: sysMgr.h:138
_GetRepeatInterval
static IARM_Result_t _GetRepeatInterval(void *arg)
Gets key repeat interval.
Definition: irMgr.c:302