• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "hdf_log.h"
10 #include "hdmi_core.h"
11 #include "securec.h"
12 
13 #define HDF_LOG_TAG hdmi_cec_c
14 
15 #define HDMI_CEC_PHY_ADDR_PHASE(addr) \
16     ((addr) >> 12), ((addr) >> 8) & 0xf, ((addr) >> 4) & 0xf, (addr) & 0xf
17 
18 typedef void (*HdmiCecHandleMsgFunc)(struct HdmiCntlr *cntlr, struct HdmiCecMsg *oldMsg, struct HdmiCecMsg *newMsg);
19 
20 struct HdmiCecHandleMsgFuncMap {
21     uint8_t opcode;
22     HdmiCecHandleMsgFunc func;
23 };
24 
25 struct HdmiCecMsgLenInfo g_cecMsg[] = {
26     { HDMI_CEC_OPCODE_ACTIVE_SOURCE, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ACTIVE_SOURCE_MSG_PARAM_LEN),
27       HDMI_CEC_MSG_BROADCAST },
28     { HDMI_CEC_OPCODE_IMAGE_VIEW_ON, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
29     { HDMI_CEC_OPCODE_TEXT_VIEW_ON, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
30     { HDMI_CEC_OPCODE_INACTIVE_SOURCE, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_INACTIVE_SOURCE_MSG_PARAM_LEN),
31       HDMI_CEC_MSG_DIRECTED },
32     { HDMI_CEC_OPCODE_REQUEST_ACTIVE_SOURCE, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_BROADCAST },
33     { HDMI_CEC_OPCODE_ROUTING_CHANGE, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ROUTING_CHANGE_MSG_PARAM_LEN),
34       HDMI_CEC_MSG_BROADCAST },
35     { HDMI_CEC_OPCODE_ROUTING_INFORMATION, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ROUTING_INFORMATIO_MSG_PARAM_LEN),
36       HDMI_CEC_MSG_BROADCAST },
37     { HDMI_CEC_OPCODE_SET_STREAM_PATH, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SET_STREAM_PATH_MSG_PARAM_LEN),
38       HDMI_CEC_MSG_BROADCAST },
39     { HDMI_CEC_OPCODE_STANDBY, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
40     { HDMI_CEC_OPCODE_RECORD_OFF, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
41     { HDMI_CEC_OPCODE_RECORD_ON, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_SOURCE_TYPE_LEN), HDMI_CEC_MSG_DIRECTED },
42     { HDMI_CEC_OPCODE_RECORD_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_STATUS_MSG_PARAM_LEN),
43       HDMI_CEC_MSG_DIRECTED },
44     { HDMI_CEC_OPCODE_RECORD_TV_SCREEN, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
45     { HDMI_CEC_OPCODE_CLEAR_ANALOGUE_TIMER, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ANALOGUE_TIMER_INFO_LEN),
46       HDMI_CEC_MSG_DIRECTED },
47     { HDMI_CEC_OPCODE_CLEAR_DIGITAL_TIMER, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DIGITAL_TIMER_INFO_LEN),
48       HDMI_CEC_MSG_DIRECTED },
49     { HDMI_CEC_OPCODE_CLEAR_EXTERNAL_TIMER, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_EXTERNAL_TIMER_INFO_LEN),
50       HDMI_CEC_MSG_DIRECTED },
51     { HDMI_CEC_OPCODE_SET_ANALOGUE_TIMER, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ANALOGUE_TIMER_INFO_LEN),
52       HDMI_CEC_MSG_DIRECTED },
53     { HDMI_CEC_OPCODE_SET_DIGITAL_TIMER, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DIGITAL_TIMER_INFO_LEN),
54       HDMI_CEC_MSG_DIRECTED },
55     { HDMI_CEC_OPCODE_SET_EXTERNAL_TIMER, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_EXTERNAL_TIMER_INFO_LEN),
56       HDMI_CEC_MSG_DIRECTED },
57     { HDMI_CEC_OPCODE_SET_TIMER_PROGRAM_TITLE, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
58     { HDMI_CEC_OPCODE_TIMER_CLEARED_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TIMER_CLEARED_STATUS_MSG_PARAM_LEN),
59       HDMI_CEC_MSG_DIRECTED },
60     { HDMI_CEC_OPCODE_TIMER_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TIMER_STATUS_DATA_MIN_LEN), HDMI_CEC_MSG_DIRECTED },
61     { HDMI_CEC_OPCODE_CEC_VERSION, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_CEC_VERSION_MSG_PARAM_LEN), HDMI_CEC_MSG_DIRECTED },
62     { HDMI_CEC_OPCODE_GET_CEC_VERSION, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
63     { HDMI_CEC_OPCODE_GIVE_PHYSICAL_ADDRESS, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
64     { HDMI_CEC_OPCODE_GET_MENU_LANGUAGE, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
65     { HDMI_CEC_OPCODE_REPORT_PHYSICAL_ADDRESS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_PHYSICAL_ADDRESS_MSG_PARAM_LEN),
66       HDMI_CEC_MSG_BROADCAST },
67     { HDMI_CEC_OPCODE_SET_MENU_LANGUAGE, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SET_MENU_LANGUAGE_MSG_PARAM_LEN),
68       HDMI_CEC_MSG_BROADCAST },
69     { HDMI_CEC_OPCODE_REPORT_FEATURES, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_FEATURES_MSG_PARAM_MIN_LEN),
70       HDMI_CEC_MSG_BROADCAST },
71     { HDMI_CEC_OPCODE_GIVE_FEATURES, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
72     { HDMI_CEC_OPCODE_DECK_CONTROL, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DECK_CONTROL_MSG_PARAM_LEN), HDMI_CEC_MSG_DIRECTED },
73     { HDMI_CEC_OPCODE_DECK_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DECK_STATUS_MSG_PARAM_LEN), HDMI_CEC_MSG_DIRECTED },
74     { HDMI_CEC_OPCODE_GIVE_DECK_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_GIVE_DECK_STATUS_MSG_PARAM_LEN),
75       HDMI_CEC_MSG_DIRECTED },
76     { HDMI_CEC_OPCODE_PLAY, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_PLAY_MSG_PARAM_LEN), HDMI_CEC_MSG_DIRECTED },
77     { HDMI_CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_GIVE_TUNER_DEVICE_STATU_MSG_PARAM_LEN),
78       HDMI_CEC_MSG_DIRECTED },
79     { HDMI_CEC_OPCODE_SELECT_ANALOGUE_SERVICE, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SELECT_ANALOGUE_SERVICE_MSG_PARAM_LEN),
80       HDMI_CEC_MSG_DIRECTED },
81     { HDMI_CEC_OPCODE_SELECT_DIGITAL_SERVICE, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SELECT_DIGITAL_SERVICE_MSG_PARAM_LEN),
82       HDMI_CEC_MSG_DIRECTED },
83     { HDMI_CEC_OPCODE_TUNER_DEVICE_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TUNER_DEVICE_STATUS_MSG_ANA_PARAM_LEN),
84       HDMI_CEC_MSG_DIRECTED },
85     { HDMI_CEC_OPCODE_TUNER_STEP_DECREMENT, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
86     { HDMI_CEC_OPCODE_TUNER_STEP_INCREMENT, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
87     { HDMI_CEC_OPCODE_DEVICE_VENDOR_ID, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DEVICE_VENDOR_ID_MSG_PARAM_LEN),
88       HDMI_CEC_MSG_DIRECTED },
89     { HDMI_CEC_OPCODE_GIVE_DEVICE_VENDOR_ID, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
90     { HDMI_CEC_OPCODE_VENDOR_COMMAND, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
91     { HDMI_CEC_OPCODE_VENDOR_COMMAND_WITH_ID, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_VENDOR_ID_LEN), HDMI_CEC_MSG_ALL },
92     { HDMI_CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_ALL },
93     { HDMI_CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_ALL },
94     { HDMI_CEC_OPCODE_SET_OSD_STRING, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DISPLAY_CONTROL_LEN), HDMI_CEC_MSG_DIRECTED },
95     { HDMI_CEC_OPCODE_GIVE_OSD_NAME, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
96     { HDMI_CEC_OPCODE_SET_OSD_NAME, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
97     { HDMI_CEC_OPCODE_MENU_REQUEST, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_MENU_REQUEST_MSG_PARAM_LEN),
98       HDMI_CEC_MSG_DIRECTED },
99     { HDMI_CEC_OPCODE_MENU_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_MENU_STATUS_MSG_PARAM_LEN), HDMI_CEC_MSG_DIRECTED },
100     { HDMI_CEC_OPCODE_USER_CONTROL_PRESSED, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_UI_COMMAND_LEN), HDMI_CEC_MSG_DIRECTED },
101     { HDMI_CEC_OPCODE_USER_CONTROL_RELEASED, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
102     { HDMI_CEC_OPCODE_GIVE_DEVICE_POWER_STATUS, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
103     { HDMI_CEC_OPCODE_REPORT_POWER_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_POWER_STATUS_MSG_PARA_LEN),
104       HDMI_CEC_MSG_DIRECTED_OR_BROADCAST_2_0 },
105     { HDMI_CEC_OPCODE_FEATURE_ABORT, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_FEATURE_ABORT_MSG_PARA_LEN),
106       HDMI_CEC_MSG_DIRECTED },
107     { HDMI_CEC_OPCODE_ABORT, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
108     { HDMI_CEC_OPCODE_GIVE_AUDIO_STATUS, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
109     { HDMI_CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
110     { HDMI_CEC_OPCODE_REPORT_AUDIO_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_AUDIO_STATUSMSG_PARAM_LEN),
111       HDMI_CEC_MSG_DIRECTED },
112     { HDMI_CEC_OPCODE_REPORT_SHORT_AUDIO_DESCRIPTOR, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
113     { HDMI_CEC_OPCODE_REQUEST_SHORT_AUDIO_DESCRIPTOR, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
114     { HDMI_CEC_OPCODE_SET_SYSTEM_AUDIO_MODE, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SYSTEM_AUDIO_STATUS_LEN),
115       HDMI_CEC_MSG_DIRECTED },
116     { HDMI_CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SYSTEM_AUDIO_MODE_REQUEST_PARAM_LEN),
117       HDMI_CEC_MSG_DIRECTED },
118     { HDMI_CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SYSTEM_AUDIO_STATUS_LEN),
119       HDMI_CEC_MSG_DIRECTED },
120     { HDMI_CEC_OPCODE_SET_AUDIO_RATE, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SET_AUDIO_RATE_PARAM_LEN),
121       HDMI_CEC_MSG_DIRECTED },
122     { HDMI_CEC_OPCODE_INITIATE_ARC, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
123     { HDMI_CEC_OPCODE_REPORT_ARC_INITIATED, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
124     { HDMI_CEC_OPCODE_REPORT_ARC_TERMINATION, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
125     { HDMI_CEC_OPCODE_REQUEST_ARC_INITIATION, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
126     { HDMI_CEC_OPCODE_REQUEST_ARC_TERMINATION, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
127     { HDMI_CEC_OPCODE_TERMINATE_ARC, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_DIRECTED },
128     { HDMI_CEC_OPCODE_CDC_MESSAGE, HDMI_CEC_GET_MSG_LEN(0), HDMI_CEC_MSG_BROADCAST },
129     { HDMI_CEC_OPCODE_REQUEST_CURRENT_LATENCY, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REQUEST_CURRENT_LATENCY_MSG_LEN),
130       HDMI_CEC_MSG_BROADCAST },
131     { HDMI_CEC_OPCODE_REPORT_CURRENT_LATENCY, HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_CURRENT_LATENCY_MSG_PARAM_MIN_LEN),
132       HDMI_CEC_MSG_BROADCAST }
133 };
134 
HdmiCecGetMsgLenInfo(uint8_t opcode)135 static struct HdmiCecMsgLenInfo *HdmiCecGetMsgLenInfo(uint8_t opcode)
136 {
137     uint32_t i;
138     uint32_t len;
139 
140     len = sizeof(g_cecMsg) / sizeof(g_cecMsg[0]);
141     for (i = 0; i < len; i++) {
142         if (opcode == g_cecMsg[i].opcode) {
143             return (&g_cecMsg[i]);
144         }
145     }
146     return NULL;
147 }
148 
HdmiCecCheckTimerStatusMsgLen(struct HdmiCecMsg * msg)149 static bool HdmiCecCheckTimerStatusMsgLen(struct HdmiCecMsg *msg)
150 {
151     /* Progremmed Info or Not Progremmed Error Info. */
152     uint8_t info = (msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] & 0xf);
153 
154     /* Progremmed Indicator Check. */
155     if ((msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] & 0x10) > 0) {
156         if (((info == HDMI_CEC_PROGRAMMED_INFO_NOT_ENOUGH_SPAC) ||
157             (info == HDMI_CEC_PROGRAMMED_INFO_MIGHT_NOT_BE_ENOUGH_SPACE)) &&
158             (msg->len < HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TIMER_STATUS_DATA_MAX_LEN))) {
159             HDF_LOGD("check Timer_Status(Indicator) Msg fail.");
160             return false;
161         }
162     } else if (info == HDMI_CEC_NOT_PROG_ERR_DUPLICATE) {
163         if (msg->len < HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TIMER_STATUS_DATA_MAX_LEN)) {
164             HDF_LOGD("check Timer_Status Msg fail.");
165             return false;
166         }
167     }
168     return true;
169 }
170 
HdmiCecCheckRecordOnMsgLen(struct HdmiCecMsg * msg)171 static bool HdmiCecCheckRecordOnMsgLen(struct HdmiCecMsg *msg)
172 {
173     switch (msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]) {
174         case HDMI_CEC_RECORD_SRC_OWN:
175             break;
176         case HDMI_CEC_RECORD_SRC_DIGITAL:
177             if (msg->len < HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_ON_DIGITAL_MSG_PARAM_LEN)) {
178                 HDF_LOGD("check Record_On(DIGITAL) Msg fail.");
179                 return false;
180             }
181             break;
182         case HDMI_CEC_RECORD_SRC_ANALOG:
183             if (msg->len < HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_ON_ANALOG_MSG_PARAM_LEN)) {
184                 HDF_LOGD("check Record_On(ANALOG) Msg fail.");
185                 return false;
186             }
187             break;
188         case HDMI_CEC_RECORD_SRC_EXT_PLUG:
189             if (msg->len < HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_ON_EXT_PLUG_MSG_PARAM_LEN)) {
190                 HDF_LOGD("check Record_On(EXT_PLUG) Msg fail.");
191                 return false;
192             }
193             break;
194         case HDMI_CEC_RECORD_SRC_EXT_PHY_ADDR:
195             if (msg->len < HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_ON_EXT_PHY_ADDR_MSG_PARAM_LEN)) {
196                 HDF_LOGD("check Record_On(EXT_PHY_ADDR) Msg fail.");
197                 return false;
198             }
199             break;
200         default:
201             break;
202     }
203     return true;
204 }
205 
HdmiCecCheckSomeSpecialfMsgLen(struct HdmiCecMsg * msg,uint8_t opcode)206 static bool HdmiCecCheckSomeSpecialfMsgLen(struct HdmiCecMsg *msg, uint8_t opcode)
207 {
208     bool ret = true;
209 
210     switch (opcode) {
211         case HDMI_CEC_OPCODE_TIMER_STATUS:
212             ret = HdmiCecCheckTimerStatusMsgLen(msg);
213             break;
214         case HDMI_CEC_OPCODE_RECORD_ON:
215             ret = HdmiCecCheckRecordOnMsgLen(msg);
216             break;
217         default:
218             break;
219     }
220     return ret;
221 }
222 
HdmiCecCheckMsgLen(struct HdmiCec * cec,struct HdmiCecMsg * msg,uint8_t opcode)223 static bool HdmiCecCheckMsgLen(struct HdmiCec *cec, struct HdmiCecMsg *msg, uint8_t opcode)
224 {
225     struct HdmiCecMsgLenInfo *info = NULL;
226 
227     info = HdmiCecGetMsgLenInfo(opcode);
228     if (info == NULL) {
229         HDF_LOGD("have no this cec msg");
230         return false;
231     }
232 
233     if (msg->len < info->minLen) {
234         HDF_LOGD("this cec msg is invalid, opcode = 0x%x, len = %d.", opcode, msg->len);
235         return false;
236     }
237     if (HdmiCecIsBroadcastMsg(msg) == true &&
238         (info->type & HDMI_CEC_MSG_BROADCAST) == 0) {
239         HDF_LOGD("this cec msg,check broadcast msg fail.");
240         return false;
241     }
242     if (HdmiCecIsBroadcastMsg(msg) == false &&
243         (info->type & HDMI_CEC_MSG_BROADCAST) > 0) {
244         HDF_LOGD("this cec msg,check directed msg fail.");
245         return false;
246     }
247     if (HdmiCecIsBroadcastMsg(msg) == true &&
248         (info->type & HDMI_CEC_MSG_BROADCAST_1_4) > 0 &&
249         cec->info.cecVersion < HDMI_CEC_VERSION_2_0) {
250         HDF_LOGD("this cec msg,check broadcast msg version fail.");
251         return false;
252     }
253     return HdmiCecCheckSomeSpecialfMsgLen(msg, opcode);
254 }
255 
256 /* message encoding/decoding functions. */
HdmiCecEncodingActiveSourceMsg(struct HdmiCecMsg * msg,uint16_t phyAddr)257 void HdmiCecEncodingActiveSourceMsg(struct HdmiCecMsg *msg, uint16_t phyAddr)
258 {
259     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ACTIVE_SOURCE_MSG_PARAM_LEN);
260     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
261     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_ACTIVE_SOURCE;
262     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
263     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
264 }
265 
HdmiCecEncodingImageViewOnMsg(struct HdmiCecMsg * msg)266 void HdmiCecEncodingImageViewOnMsg(struct HdmiCecMsg *msg)
267 {
268     msg->len = HDMI_CEC_GET_MSG_LEN(0);
269     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_IMAGE_VIEW_ON;
270 }
271 
HdmiCecEncodingTextViewOnMsg(struct HdmiCecMsg * msg)272 void HdmiCecEncodingTextViewOnMsg(struct HdmiCecMsg *msg)
273 {
274     msg->len = HDMI_CEC_GET_MSG_LEN(0);
275     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_TEXT_VIEW_ON;
276 }
277 
HdmiCecEncodingInactiveSourceMsg(struct HdmiCecMsg * msg,uint16_t phyAddr)278 void HdmiCecEncodingInactiveSourceMsg(struct HdmiCecMsg *msg, uint16_t phyAddr)
279 {
280     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_INACTIVE_SOURCE_MSG_PARAM_LEN);
281     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_INACTIVE_SOURCE;
282     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
283     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
284 }
285 
HdmiCecEncodingRequestActiveSourceMsg(struct HdmiCecMsg * msg,bool response)286 void HdmiCecEncodingRequestActiveSourceMsg(struct HdmiCecMsg *msg, bool response)
287 {
288     msg->len = HDMI_CEC_GET_MSG_LEN(0);
289     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
290     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REQUEST_ACTIVE_SOURCE;
291     if (response == true) {
292         msg->rspMsg = HDMI_CEC_OPCODE_ACTIVE_SOURCE;
293     }
294 }
295 
HdmiCecEncodingRoutingChangeMsg(struct HdmiCecMsg * msg,uint16_t orgAddr,uint16_t newAddr,bool response)296 void HdmiCecEncodingRoutingChangeMsg(struct HdmiCecMsg *msg, uint16_t orgAddr, uint16_t newAddr, bool response)
297 {
298     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ROUTING_CHANGE_MSG_PARAM_LEN);
299     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
300     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_ROUTING_CHANGE;
301     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (orgAddr >> HDMI_ONE_BYTE_SHIFT);
302     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (orgAddr & HDMI_ONE_BYTE_MARK);
303     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = (newAddr >> HDMI_ONE_BYTE_SHIFT);
304     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (newAddr & HDMI_ONE_BYTE_MARK);
305     if (response == true) {
306         msg->rspMsg = HDMI_CEC_OPCODE_ROUTING_INFORMATION;
307     }
308 }
309 
HdmiCecEncodingRoutingInfomationMsg(struct HdmiCecMsg * msg,uint16_t phyAddr)310 void HdmiCecEncodingRoutingInfomationMsg(struct HdmiCecMsg *msg, uint16_t phyAddr)
311 {
312     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ROUTING_INFORMATIO_MSG_PARAM_LEN);
313     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
314     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_ROUTING_INFORMATION;
315     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
316     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
317 }
318 
HdmiCecEncodingSetStreamPathMsg(struct HdmiCecMsg * msg,uint16_t phyAddr)319 void HdmiCecEncodingSetStreamPathMsg(struct HdmiCecMsg *msg, uint16_t phyAddr)
320 {
321     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SET_STREAM_PATH_MSG_PARAM_LEN);
322     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
323     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_STREAM_PATH;
324     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
325     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
326 }
327 
HdmiCecEncodingStandbyMsg(struct HdmiCecMsg * msg)328 void HdmiCecEncodingStandbyMsg(struct HdmiCecMsg *msg)
329 {
330     msg->len = HDMI_CEC_GET_MSG_LEN(0);
331     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_STANDBY;
332 }
333 
HdmiCecEncodingRecordOffMsg(struct HdmiCecMsg * msg,bool response)334 void HdmiCecEncodingRecordOffMsg(struct HdmiCecMsg *msg, bool response)
335 {
336     msg->len = HDMI_CEC_GET_MSG_LEN(0);
337     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_RECORD_OFF;
338     if (response == true) {
339         msg->rspMsg = HDMI_CEC_OPCODE_RECORD_STATUS;
340     }
341 }
342 
HdmiCecEncodingRecordOnOwn(struct HdmiCecMsg * msg)343 static void HdmiCecEncodingRecordOnOwn(struct HdmiCecMsg *msg)
344 {
345     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_SOURCE_TYPE_LEN);
346     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_RECORD_ON;
347     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = HDMI_CEC_RECORD_SRC_OWN;
348 }
349 
HdmiCecEncodingDigitalServiceId(uint8_t * data,uint8_t len,const struct HdmiCecDigitalServiceId * digital)350 static void HdmiCecEncodingDigitalServiceId(uint8_t *data, uint8_t len, const struct HdmiCecDigitalServiceId *digital)
351 {
352     if (len < HDMI_CEC_DIGITAL_SERVICE_ID_LEN) {
353         return;
354     }
355 
356     data[DATA_ZEROTH_OFFSET_ELEMENT] = (digital->method << HDMI_CEC_DIGITAL_SERVICE_ID_METHOD_SHIFT) |
357                                        (digital->system);
358     if (digital->method == HDMI_CEC_SERVICE_ID_METHOD_BY_CHANNEL) {
359         data[DATA_FIRST_OFFSET_ELEMENT] =
360             (digital->systemData.channel.format << HDMI_CEC_CHANNEL_NUMBER_FORMAT_SHIFT) |
361             (digital->systemData.channel.major >> HDMI_ONE_BYTE_SHIFT);
362         data[DATA_SECOND_OFFSET_ELEMENT] = digital->systemData.channel.major & HDMI_ONE_BYTE_MARK;
363         data[DATA_THIRD_OFFSET_ELEMENT] = digital->systemData.channel.minor >> HDMI_ONE_BYTE_SHIFT;
364         data[DATA_FORTH_OFFSET_ELEMENT] = digital->systemData.channel.minor & HDMI_ONE_BYTE_MARK;
365         return;
366     }
367     switch (digital->system) {
368         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN:
369         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS:
370         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS:
371         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_ARIB_T:
372             data[DATA_FIRST_OFFSET_ELEMENT] = digital->systemData.arib.transportId >> HDMI_ONE_BYTE_SHIFT;
373             data[DATA_SECOND_OFFSET_ELEMENT] = digital->systemData.arib.transportId & HDMI_ONE_BYTE_MARK;
374             data[DATA_THIRD_OFFSET_ELEMENT] = digital->systemData.arib.serviceId >> HDMI_ONE_BYTE_SHIFT;
375             data[DATA_FORTH_OFFSET_ELEMENT] = digital->systemData.arib.serviceId & HDMI_ONE_BYTE_MARK;
376             data[DATA_FIFTH_OFFSET_ELEMENT] = digital->systemData.arib.orgNetworkId >> HDMI_ONE_BYTE_SHIFT;
377             data[DATA_SIXTH_OFFSET_ELEMENT] = digital->systemData.arib.orgNetworkId & HDMI_ONE_BYTE_MARK;
378             break;
379         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:
380         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:
381         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_ATSC_SATELLITE:
382         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_ATSC_TERRESTRIAL:
383             data[DATA_FIRST_OFFSET_ELEMENT] = digital->systemData.atsc.transportId >> HDMI_ONE_BYTE_SHIFT;
384             data[DATA_SECOND_OFFSET_ELEMENT] = digital->systemData.atsc.transportId & HDMI_ONE_BYTE_MARK;
385             data[DATA_THIRD_OFFSET_ELEMENT] = digital->systemData.atsc.programNumber >> HDMI_ONE_BYTE_SHIFT;
386             data[DATA_FORTH_OFFSET_ELEMENT] = digital->systemData.atsc.programNumber & HDMI_ONE_BYTE_MARK;
387             break;
388         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN:
389         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_DVB_C:
390         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_DVB_S:
391         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_DVB_S2:
392         case HDMI_CEC_DIG_SERVICE_BCAST_SYSTEM_DVB_T:
393             data[DATA_FIRST_OFFSET_ELEMENT] = digital->systemData.dvb.transportId >> HDMI_ONE_BYTE_SHIFT;
394             data[DATA_SECOND_OFFSET_ELEMENT] = digital->systemData.dvb.transportId & HDMI_ONE_BYTE_MARK;
395             data[DATA_THIRD_OFFSET_ELEMENT] = digital->systemData.dvb.serviceId >> HDMI_ONE_BYTE_SHIFT;
396             data[DATA_FORTH_OFFSET_ELEMENT] = digital->systemData.dvb.serviceId & HDMI_ONE_BYTE_MARK;
397             data[DATA_FIFTH_OFFSET_ELEMENT] = digital->systemData.dvb.orgNetworkId >> HDMI_ONE_BYTE_SHIFT;
398             data[DATA_SIXTH_OFFSET_ELEMENT] = digital->systemData.dvb.orgNetworkId & HDMI_ONE_BYTE_MARK;
399             break;
400         default:
401             HDF_LOGE("digital system 0x%x is invalid", digital->system);
402     }
403 }
404 
HdmiCecEncodingRecordOnDigital(struct HdmiCecMsg * msg,struct HdmiCecDigitalServiceId * digital)405 static void HdmiCecEncodingRecordOnDigital(struct HdmiCecMsg *msg, struct HdmiCecDigitalServiceId *digital)
406 {
407     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_ON_DIGITAL_MSG_PARAM_LEN);
408     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_RECORD_ON;
409     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = HDMI_CEC_RECORD_SRC_DIGITAL;
410     HdmiCecEncodingDigitalServiceId(&(msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT]),
411                                     HDMI_CEC_DIGITAL_SERVICE_ID_LEN,
412                                     digital);
413 }
414 
HdmiCecEncodingRecordOnAnalog(struct HdmiCecMsg * msg,uint8_t anaBcastType,uint16_t anaFreq,uint8_t bcstSystem)415 static void HdmiCecEncodingRecordOnAnalog(struct HdmiCecMsg *msg,
416     uint8_t anaBcastType, uint16_t anaFreq, uint8_t bcstSystem)
417 {
418     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_ON_ANALOG_MSG_PARAM_LEN);
419     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_RECORD_ON;
420     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = HDMI_CEC_RECORD_SRC_ANALOG;
421     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = anaBcastType;
422     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = (anaFreq >> HDMI_ONE_BYTE_SHIFT);
423     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (anaFreq & HDMI_ONE_BYTE_MARK);
424     msg->data[HDMI_CEC_MSG_DATA_SIXTH_ELEMENT] = bcstSystem;
425 }
426 
HdmiCecEncodingRecordOnExtPlug(struct HdmiCecMsg * msg,uint8_t extPlug)427 static void HdmiCecEncodingRecordOnExtPlug(struct HdmiCecMsg *msg, uint8_t extPlug)
428 {
429     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_ON_EXT_PLUG_MSG_PARAM_LEN);
430     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_RECORD_ON;
431     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = HDMI_CEC_RECORD_SRC_EXT_PLUG;
432     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = extPlug;
433 }
434 
HdmiCecEncodingRecordOnExtPhyAddr(struct HdmiCecMsg * msg,uint16_t extPhyAddr)435 static void HdmiCecEncodingRecordOnExtPhyAddr(struct HdmiCecMsg *msg, uint16_t extPhyAddr)
436 {
437     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_ON_EXT_PHY_ADDR_MSG_PARAM_LEN);
438     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_RECORD_ON;
439     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = HDMI_CEC_RECORD_SRC_EXT_PHY_ADDR;
440     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (extPhyAddr >> HDMI_ONE_BYTE_SHIFT);
441     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = (extPhyAddr & HDMI_ONE_BYTE_MARK);
442 }
443 
HdmiCecEncodingRecordOnMsg(struct HdmiCecMsg * msg,struct HdmiCecRecordSource * src,bool response)444 void HdmiCecEncodingRecordOnMsg(struct HdmiCecMsg *msg, struct HdmiCecRecordSource *src, bool response)
445 {
446     switch (src->type) {
447         case HDMI_CEC_RECORD_SRC_OWN:
448             HdmiCecEncodingRecordOnOwn(msg);
449             break;
450         case HDMI_CEC_RECORD_SRC_DIGITAL:
451             HdmiCecEncodingRecordOnDigital(msg, &(src->data.id));
452             break;
453         case HDMI_CEC_RECORD_SRC_ANALOG:
454             HdmiCecEncodingRecordOnAnalog(msg, src->data.analog.anaBcastType,
455                 src->data.analog.anaFreq, src->data.analog.bcstSystem);
456             break;
457         case HDMI_CEC_RECORD_SRC_EXT_PLUG:
458             HdmiCecEncodingRecordOnExtPlug(msg, src->data.extPlug);
459             break;
460         case HDMI_CEC_RECORD_SRC_EXT_PHY_ADDR:
461             HdmiCecEncodingRecordOnExtPhyAddr(msg, src->data.extPhyAddr);
462             break;
463         default:
464             HDF_LOGE("cec record on: type %d unknow", src->type);
465     }
466 
467     if (response == true) {
468         msg->rspMsg = HDMI_CEC_OPCODE_RECORD_STATUS;
469     }
470 }
471 
HdmiCecEncodingRecordStatusMsg(struct HdmiCecMsg * msg,uint8_t recordStatusInfo)472 void HdmiCecEncodingRecordStatusMsg(struct HdmiCecMsg *msg, uint8_t recordStatusInfo)
473 {
474     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_RECORD_STATUS_MSG_PARAM_LEN);
475     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_RECORD_STATUS;
476     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = recordStatusInfo;
477 }
478 
HdmiCecEncodingRecordTvScreenMsg(struct HdmiCecMsg * msg,bool response)479 void HdmiCecEncodingRecordTvScreenMsg(struct HdmiCecMsg *msg, bool response)
480 {
481     msg->len = HDMI_CEC_GET_MSG_LEN(0);
482     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_RECORD_TV_SCREEN;
483     if (response == true) {
484         msg->rspMsg = HDMI_CEC_OPCODE_RECORD_ON;
485     }
486 }
487 
HdmiCecEncodingCommTimerInfo(uint8_t * data,uint8_t len,const struct HdmiCecCommTimerInfo * info)488 static void HdmiCecEncodingCommTimerInfo(uint8_t *data, uint8_t len, const struct HdmiCecCommTimerInfo *info)
489 {
490     if (len < HDMI_CEC_COMM_TIMER_INFO_LEN) {
491         return;
492     }
493     data[DATA_ZEROTH_OFFSET_ELEMENT] = info->data;
494     data[DATA_FIRST_OFFSET_ELEMENT] = info->month;
495     data[DATA_SECOND_OFFSET_ELEMENT] = HDMI_CEC_BCD_FORMAT_TIME(info->startHour);
496     data[DATA_THIRD_OFFSET_ELEMENT] = HDMI_CEC_BCD_FORMAT_TIME(info->startMinute);
497     data[DATA_FORTH_OFFSET_ELEMENT] = HDMI_CEC_BCD_FORMAT_TIME(info->durationHour);
498     data[DATA_FIFTH_OFFSET_ELEMENT] = HDMI_CEC_BCD_FORMAT_TIME(info->durationMinute);
499     data[DATA_SIXTH_OFFSET_ELEMENT] = info->recordingSeq;
500 }
501 
HdmiCecEncodingAnalogueTimerInfo(uint8_t * data,uint8_t len,struct HdmiCecAnalogueTimerInfo * info)502 static void HdmiCecEncodingAnalogueTimerInfo(uint8_t *data, uint8_t len, struct HdmiCecAnalogueTimerInfo *info)
503 {
504     if (len < HDMI_CEC_ANALOGUE_TIMER_INFO_LEN) {
505         return;
506     }
507     HdmiCecEncodingCommTimerInfo(data, HDMI_CEC_COMM_TIMER_INFO_LEN, &(info->commInfo));
508     data[DATA_SEVENTH_OFFSET_ELEMENT] = info->anaBcastType;
509     data[DATA_EIGHTH_OFFSET_ELEMENT] = (info->anaFreq >> HDMI_ONE_BYTE_SHIFT);
510     data[DATA_NINTH_OFFSET_ELEMENT] = (info->anaFreq & HDMI_ONE_BYTE_MARK);
511     data[DATA_TENTH_OFFSET_ELEMENT] = info->bcstSystem;
512 }
513 
HdmiCecEncodingClearAnalogueTimerMsg(struct HdmiCecMsg * msg,struct HdmiCecAnalogueTimerInfo * info,bool response)514 void HdmiCecEncodingClearAnalogueTimerMsg(struct HdmiCecMsg *msg, struct HdmiCecAnalogueTimerInfo *info, bool response)
515 {
516     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ANALOGUE_TIMER_INFO_LEN);
517     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CLEAR_ANALOGUE_TIMER;
518     HdmiCecEncodingAnalogueTimerInfo(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]),
519                                      HDMI_CEC_ANALOGUE_TIMER_INFO_LEN,
520                                      info);
521     if (response == true) {
522         msg->rspMsg = HDMI_CEC_OPCODE_TIMER_CLEARED_STATUS;
523     }
524 }
525 
HdmiCecEncodingDigitalTimerInfo(uint8_t * data,uint8_t len,struct HdmiCecDigitalTimerInfo * info)526 static void HdmiCecEncodingDigitalTimerInfo(uint8_t *data, uint8_t len, struct HdmiCecDigitalTimerInfo *info)
527 {
528     if (len < HDMI_CEC_DIGITAL_TIMER_INFO_LEN) {
529         return;
530     }
531     HdmiCecEncodingCommTimerInfo(data, HDMI_CEC_COMM_TIMER_INFO_LEN, &(info->commInfo));
532     HdmiCecEncodingDigitalServiceId(&data[DATA_SEVENTH_OFFSET_ELEMENT],
533                                     len - HDMI_CEC_COMM_TIMER_INFO_LEN,
534                                     &(info->id));
535 }
536 
HdmiCecEncodingClearDigitalTimerMsg(struct HdmiCecMsg * msg,struct HdmiCecDigitalTimerInfo * info,bool response)537 void HdmiCecEncodingClearDigitalTimerMsg(struct HdmiCecMsg *msg, struct HdmiCecDigitalTimerInfo *info, bool response)
538 {
539     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DIGITAL_TIMER_INFO_LEN);
540     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CLEAR_DIGITAL_TIMER;
541     HdmiCecEncodingDigitalTimerInfo(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]),
542                                     HDMI_CEC_DIGITAL_TIMER_INFO_LEN,
543                                     info);
544     if (response == true) {
545         msg->rspMsg = HDMI_CEC_OPCODE_TIMER_CLEARED_STATUS;
546     }
547 }
548 
HdmiCecEncodingExternalTimerInfo(uint8_t * data,uint8_t len,struct HdmiCecExternalTimerInfo * info)549 static void HdmiCecEncodingExternalTimerInfo(uint8_t *data, uint8_t len, struct HdmiCecExternalTimerInfo *info)
550 {
551     if (len < HDMI_CEC_EXTERNAL_TIMER_INFO_LEN) {
552         return;
553     }
554     HdmiCecEncodingCommTimerInfo(data, HDMI_CEC_COMM_TIMER_INFO_LEN, &(info->commInfo));
555     data[DATA_SEVENTH_OFFSET_ELEMENT] = info->extSrcSpec;
556     data[DATA_EIGHTH_OFFSET_ELEMENT] = info->extPlug;
557     data[DATA_NINTH_OFFSET_ELEMENT] = (info->extPhyAddr >> HDMI_ONE_BYTE_SHIFT);
558     data[DATA_TENTH_OFFSET_ELEMENT] = (info->extPhyAddr & HDMI_ONE_BYTE_MARK);
559 }
560 
HdmiCecEncodingClearExternalTimerMsg(struct HdmiCecMsg * msg,struct HdmiCecExternalTimerInfo * info,bool response)561 void HdmiCecEncodingClearExternalTimerMsg(struct HdmiCecMsg *msg, struct HdmiCecExternalTimerInfo *info, bool response)
562 {
563     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_EXTERNAL_TIMER_INFO_LEN);
564     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CLEAR_EXTERNAL_TIMER;
565     HdmiCecEncodingExternalTimerInfo(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]),
566                                      HDMI_CEC_EXTERNAL_TIMER_INFO_LEN,
567                                      info);
568     if (response == true) {
569         msg->rspMsg = HDMI_CEC_OPCODE_TIMER_CLEARED_STATUS;
570     }
571 }
572 
HdmiCecEncodingSetAnalogueTimerMsg(struct HdmiCecMsg * msg,struct HdmiCecAnalogueTimerInfo * info,bool response)573 void HdmiCecEncodingSetAnalogueTimerMsg(struct HdmiCecMsg *msg, struct HdmiCecAnalogueTimerInfo *info, bool response)
574 {
575     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_ANALOGUE_TIMER_INFO_LEN);
576     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_ANALOGUE_TIMER;
577     HdmiCecEncodingAnalogueTimerInfo(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]),
578                                      HDMI_CEC_ANALOGUE_TIMER_INFO_LEN,
579                                      info);
580     if (response == true) {
581         msg->rspMsg = HDMI_CEC_OPCODE_TIMER_STATUS;
582     }
583 }
584 
HdmiCecEncodingSetDigitalTimerMsg(struct HdmiCecMsg * msg,struct HdmiCecDigitalTimerInfo * info,bool response)585 void HdmiCecEncodingSetDigitalTimerMsg(struct HdmiCecMsg *msg, struct HdmiCecDigitalTimerInfo *info, bool response)
586 {
587     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DIGITAL_TIMER_INFO_LEN);
588     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_DIGITAL_TIMER;
589     HdmiCecEncodingDigitalTimerInfo(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]),
590                                     HDMI_CEC_DIGITAL_TIMER_INFO_LEN,
591                                     info);
592     if (response == true) {
593         msg->rspMsg = HDMI_CEC_OPCODE_TIMER_STATUS;
594     }
595 }
596 
HdmiCecEncodingSetExternalTimerMsg(struct HdmiCecMsg * msg,struct HdmiCecExternalTimerInfo * info,bool response)597 void HdmiCecEncodingSetExternalTimerMsg(struct HdmiCecMsg *msg, struct HdmiCecExternalTimerInfo *info, bool response)
598 {
599     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_EXTERNAL_TIMER_INFO_LEN);
600     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_EXTERNAL_TIMER;
601     HdmiCecEncodingExternalTimerInfo(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]),
602                                      HDMI_CEC_EXTERNAL_TIMER_INFO_LEN,
603                                      info);
604     if (response == true) {
605         msg->rspMsg = HDMI_CEC_OPCODE_TIMER_STATUS;
606     }
607 }
608 
HdmiCecEncodingSetTimerProgramTitleMsg(struct HdmiCecMsg * msg,uint8_t * title,uint32_t len)609 void HdmiCecEncodingSetTimerProgramTitleMsg(struct HdmiCecMsg *msg, uint8_t *title, uint32_t len)
610 {
611     uint32_t length;
612 
613     if (title == NULL || len < HDMI_CEC_PROGRAM_TITLE_STR_MIN_LEN) {
614         HDF_LOGE("encoding set timer program title, input param invalid.");
615         return;
616     }
617     length = ((len <= HDMI_CEC_PROGRAM_TITLE_STR_MAX_LEN) ? len : HDMI_CEC_PROGRAM_TITLE_STR_MAX_LEN);
618     msg->len = HDMI_CEC_GET_MSG_LEN(length);
619     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_TIMER_PROGRAM_TITLE;
620     if (memcpy_s(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]), (msg->len - HDMI_CEC_MSG_DATA_SECOND_ELEMENT),
621         title, length) != EOK) {
622         HDF_LOGE("encoding set timer program title, memcpy_s fail.");
623     }
624 }
625 
HdmiCecEncodingTimerClearedStatusMsg(struct HdmiCecMsg * msg,uint8_t status)626 void HdmiCecEncodingTimerClearedStatusMsg(struct HdmiCecMsg *msg, uint8_t status)
627 {
628     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TIMER_CLEARED_STATUS_MSG_PARAM_LEN);
629     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_TIMER_CLEARED_STATUS;
630     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = status;
631 }
632 
HdmiCecEncodingTimerStatusMsg(struct HdmiCecMsg * msg,const struct HdmiCecTimerStatusData * status)633 void HdmiCecEncodingTimerStatusMsg(struct HdmiCecMsg *msg, const struct HdmiCecTimerStatusData *status)
634 {
635     bool duration = false;
636 
637     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TIMER_STATUS_DATA_MIN_LEN);
638     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_TIMER_STATUS;
639     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] |= (status->timerOverlap << HDMI_CEC_TIMER_OVERLAP_WARNING_SHIFT);
640     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] |= (status->mediaInfo << HDMI_CEC_MEDIA_INFO_SHIFT);
641     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] |= (status->progInfo.indicator << HDMI_CEC_PROG_IND_SHIFT);
642     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] |= (status->progInfo.info);
643     if (status->progInfo.indicator > 0) {
644         /* Progremmed Info */
645         if (status->progInfo.info == HDMI_CEC_PROGRAMMED_INFO_NOT_ENOUGH_SPAC ||
646             status->progInfo.info == HDMI_CEC_PROGRAMMED_INFO_MIGHT_NOT_BE_ENOUGH_SPACE) {
647             duration = true;
648         }
649     } else {
650         /* Not Progremmed Error Info */
651         if (status->progInfo.info == HDMI_CEC_NOT_PROG_ERR_DUPLICATE) {
652             duration = true;
653         }
654     }
655     if (duration == true) {
656         msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TIMER_STATUS_DATA_MAX_LEN);
657         msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = HDMI_CEC_BCD_FORMAT_TIME(status->progInfo.durationHour);
658         msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CEC_BCD_FORMAT_TIME(status->progInfo.durationMinute);
659     }
660 }
661 
HdmiCecEncodingCecVersionMsg(struct HdmiCecMsg * msg,uint8_t version)662 static void HdmiCecEncodingCecVersionMsg(struct HdmiCecMsg *msg, uint8_t version)
663 {
664     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_CEC_VERSION_MSG_PARAM_LEN);
665     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CEC_VERSION;
666     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = version;
667 }
668 
HdmiCecEncodingGetCecVersionMsg(struct HdmiCecMsg * msg,bool response)669 void HdmiCecEncodingGetCecVersionMsg(struct HdmiCecMsg *msg, bool response)
670 {
671     if (msg == NULL) {
672         HDF_LOGE("%s: msg is null", __func__);
673         return;
674     }
675 
676     msg->len = HDMI_CEC_GET_MSG_LEN(0);
677     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GET_CEC_VERSION;
678     if (response == true) {
679         msg->rspMsg = HDMI_CEC_OPCODE_CEC_VERSION;
680     }
681 }
682 
HdmiCecEncodingGetPhyAddressMsg(struct HdmiCecMsg * msg,bool response)683 void HdmiCecEncodingGetPhyAddressMsg(struct HdmiCecMsg *msg, bool response)
684 {
685     msg->len = HDMI_CEC_GET_MSG_LEN(0);
686     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_PHYSICAL_ADDRESS;
687     if (response == true) {
688         msg->rspMsg = HDMI_CEC_OPCODE_REPORT_PHYSICAL_ADDRESS;
689     }
690 }
691 
HdmiCecEncodingGetMenuLanguageMsg(struct HdmiCecMsg * msg,bool response)692 void HdmiCecEncodingGetMenuLanguageMsg(struct HdmiCecMsg *msg, bool response)
693 {
694     msg->len = HDMI_CEC_GET_MSG_LEN(0);
695     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GET_MENU_LANGUAGE;
696     if (response == true) {
697         msg->rspMsg = HDMI_CEC_OPCODE_SET_MENU_LANGUAGE;
698     }
699 }
700 
HdmiCecEncodingReportPhyAddressMsg(struct HdmiCecMsg * msg,uint16_t phyAddr,uint8_t deviceType)701 static void HdmiCecEncodingReportPhyAddressMsg(struct HdmiCecMsg *msg, uint16_t phyAddr, uint8_t deviceType)
702 {
703     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_PHYSICAL_ADDRESS_MSG_PARAM_LEN);
704     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
705     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REPORT_PHYSICAL_ADDRESS;
706     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
707     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
708     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = deviceType;
709 }
710 
HdmiCecEncodingSetMenuLanguageMsg(struct HdmiCecMsg * msg,uint8_t * language,uint32_t len)711 void HdmiCecEncodingSetMenuLanguageMsg(struct HdmiCecMsg *msg, uint8_t *language, uint32_t len)
712 {
713     if (language == NULL || len != HDMI_CEC_SET_MENU_LANGUAGE_MSG_PARAM_LEN) {
714         HDF_LOGE("encoding set menu language, input param invalid.");
715         return;
716     }
717 
718     msg->len = HDMI_CEC_GET_MSG_LEN(len);
719     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
720     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_MENU_LANGUAGE;
721     if (memcpy_s(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]), (msg->len - HDMI_CEC_MSG_DATA_SECOND_ELEMENT),
722         language, len) != EOK) {
723         HDF_LOGE("encoding set menu language, memcpy_s fail.");
724     }
725 }
726 
HdmiCecEncodingReportFeaturesMsg(struct HdmiCecMsg * msg,const struct HdmiCecInfo * info)727 static void HdmiCecEncodingReportFeaturesMsg(struct HdmiCecMsg *msg, const struct HdmiCecInfo *info)
728 {
729     uint32_t i;
730 
731     msg->len = HDMI_CEC_GET_MSG_LEN(0);
732     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
733     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REPORT_FEATURES;
734     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = info->cecVersion;
735     msg->len++;
736     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = info->allDeviceType;
737     msg->len++;
738     /* fill RC Profile. */
739     for (i = 0; i < HDMI_CEC_RC_PROFILE_MAX_NUM; i++) {
740         msg->data[msg->len] = info->rcProfile[i];
741         msg->len++;
742         if ((info->rcProfile[i] & HDMI_CEC_RC_PROFILE_EXTERNSION_MARK) == 0) {
743             break;
744         }
745     }
746     /* fill Device Features. */
747     for (i = 0; i < HDMI_CEC_DEVICE_FEATURES_MAX_NUM; i++) {
748         msg->data[msg->len] = info->devFeatures[i];
749         msg->len++;
750         if ((info->devFeatures[i] & HDMI_CEC_DEVICE_FEATURES_EXTERNSION_MARK) == 0) {
751             break;
752         }
753     }
754 }
755 
HdmiCecEncodingGiveFeaturesMsg(struct HdmiCecMsg * msg,bool response)756 void HdmiCecEncodingGiveFeaturesMsg(struct HdmiCecMsg *msg, bool response)
757 {
758     msg->len = HDMI_CEC_GET_MSG_LEN(0);
759     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_FEATURES;
760     if (response == true) {
761         msg->rspMsg = HDMI_CEC_OPCODE_SET_MENU_LANGUAGE;
762     }
763 }
764 
765 
HdmiCecEncodingDeckControlMsg(struct HdmiCecMsg * msg,uint8_t mode)766 void HdmiCecEncodingDeckControlMsg(struct HdmiCecMsg *msg, uint8_t mode)
767 {
768     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DECK_CONTROL_MSG_PARAM_LEN);
769     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_DECK_CONTROL;
770     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = mode;
771 }
772 
HdmiCecEncodingDeckStatusMsg(struct HdmiCecMsg * msg,uint8_t info)773 void HdmiCecEncodingDeckStatusMsg(struct HdmiCecMsg *msg, uint8_t info)
774 {
775     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DECK_STATUS_MSG_PARAM_LEN);
776     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_DECK_STATUS;
777     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = info;
778 }
779 
HdmiCecEncodingGiveDeckStatusMsg(struct HdmiCecMsg * msg,uint8_t statusReq,bool response)780 void HdmiCecEncodingGiveDeckStatusMsg(struct HdmiCecMsg *msg, uint8_t statusReq, bool response)
781 {
782     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_GIVE_DECK_STATUS_MSG_PARAM_LEN);
783     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_DECK_STATUS;
784     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = statusReq;
785     if (response == true) {
786         msg->rspMsg = HDMI_CEC_OPCODE_DECK_STATUS;
787     }
788 }
789 
HdmiCecEncodingPlayMsg(struct HdmiCecMsg * msg,uint8_t playMode)790 void HdmiCecEncodingPlayMsg(struct HdmiCecMsg *msg, uint8_t playMode)
791 {
792     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_PLAY_MSG_PARAM_LEN);
793     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_PLAY;
794     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = playMode;
795 }
796 
HdmiCecEncodingGiveTunerDeviceStatusMsg(struct HdmiCecMsg * msg,uint8_t statusReq,bool response)797 void HdmiCecEncodingGiveTunerDeviceStatusMsg(struct HdmiCecMsg *msg, uint8_t statusReq, bool response)
798 {
799     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_GIVE_TUNER_DEVICE_STATU_MSG_PARAM_LEN);
800     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_TUNER_DEVICE_STATUS;
801     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = statusReq;
802     if (response == true) {
803         msg->rspMsg = HDMI_CEC_OPCODE_TUNER_DEVICE_STATUS;
804     }
805 }
806 
HdmiCecEncodingSelectAnalogueServiceMsg(struct HdmiCecMsg * msg,uint8_t anaBcastType,uint16_t anaFreq,uint8_t bcstSystem)807 void HdmiCecEncodingSelectAnalogueServiceMsg(struct HdmiCecMsg *msg,
808     uint8_t anaBcastType, uint16_t anaFreq, uint8_t bcstSystem)
809 {
810     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SELECT_ANALOGUE_SERVICE_MSG_PARAM_LEN);
811     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SELECT_ANALOGUE_SERVICE;
812     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = anaBcastType;
813     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (anaFreq >> HDMI_ONE_BYTE_SHIFT);
814     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = (anaFreq & HDMI_ONE_BYTE_MARK);
815     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = bcstSystem;
816 }
817 
HdmiCecEncodingSelectDigitalServiceMsg(struct HdmiCecMsg * msg,struct HdmiCecDigitalServiceId * digital)818 void HdmiCecEncodingSelectDigitalServiceMsg(struct HdmiCecMsg *msg, struct HdmiCecDigitalServiceId *digital)
819 {
820     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SELECT_DIGITAL_SERVICE_MSG_PARAM_LEN);
821     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SELECT_DIGITAL_SERVICE;
822     HdmiCecEncodingDigitalServiceId(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]),
823                                     HDMI_CEC_SELECT_DIGITAL_SERVICE_MSG_PARAM_LEN,
824                                     digital);
825 }
826 
HdmiCecEncodingTunerDeviceStatusMsg(struct HdmiCecMsg * msg,const struct HdmiCecTunerDeviceInfo * info)827 void HdmiCecEncodingTunerDeviceStatusMsg(struct HdmiCecMsg *msg, const struct HdmiCecTunerDeviceInfo *info)
828 {
829     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_TUNER_DEVICE_STATUS;
830     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (info->recordingFlag << HDMI_CEC_RECORDING_FALG_SHIFT) |
831         (info->dispInfo);
832     if (info->isAnalogService == true) {
833         msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TUNER_DEVICE_STATUS_MSG_ANA_PARAM_LEN);
834         msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = info->data.analog.anaBcastType;
835         msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = (info->data.analog.anaFreq >> HDMI_ONE_BYTE_SHIFT);
836         msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (info->data.analog.anaFreq & HDMI_ONE_BYTE_MARK);
837         msg->data[HDMI_CEC_MSG_DATA_SIXTH_ELEMENT] = info->data.analog.bcstSystem;
838     } else {
839         msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_TUNER_DEVICE_STATUS_MSG_DIG_PARAM_LEN);
840         HdmiCecEncodingDigitalServiceId(&(msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT]),
841                                         HDMI_CEC_SELECT_DIGITAL_SERVICE_MSG_PARAM_LEN,
842                                         &(info->data.digital));
843     }
844 }
845 
HdmiCecEncodingTunerStepDecrementMsg(struct HdmiCecMsg * msg)846 void HdmiCecEncodingTunerStepDecrementMsg(struct HdmiCecMsg *msg)
847 {
848     msg->len = HDMI_CEC_GET_MSG_LEN(0);
849     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_TUNER_STEP_DECREMENT;
850 }
851 
HdmiCecEncodingTunerStepIncrementMsg(struct HdmiCecMsg * msg)852 void HdmiCecEncodingTunerStepIncrementMsg(struct HdmiCecMsg *msg)
853 {
854     msg->len = HDMI_CEC_GET_MSG_LEN(0);
855     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_TUNER_STEP_INCREMENT;
856 }
857 
HdmiCecEncodingDeviceVendorIdMsg(struct HdmiCecMsg * msg,uint32_t devVendorId)858 static void HdmiCecEncodingDeviceVendorIdMsg(struct HdmiCecMsg *msg, uint32_t devVendorId)
859 {
860     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_DEVICE_VENDOR_ID_MSG_PARAM_LEN);
861     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_DEVICE_VENDOR_ID;
862     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (devVendorId >> HDMI_TWO_BYTES_SHIFT) & HDMI_ONE_BYTE_MARK;
863     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (devVendorId >> HDMI_ONE_BYTE_SHIFT) & HDMI_ONE_BYTE_MARK;
864     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = (devVendorId & HDMI_ONE_BYTE_MARK);
865 }
866 
HdmiCecEncodingGiveDeviceVendorIdMsg(struct HdmiCecMsg * msg,bool response)867 void HdmiCecEncodingGiveDeviceVendorIdMsg(struct HdmiCecMsg *msg, bool response)
868 {
869     msg->len = HDMI_CEC_GET_MSG_LEN(0);
870     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_DEVICE_VENDOR_ID;
871     if (response == true) {
872         msg->rspMsg = HDMI_CEC_OPCODE_DEVICE_VENDOR_ID;
873     }
874 }
875 
HdmiCecEncodingVendorCommandMsg(struct HdmiCecMsg * msg,uint8_t * data,uint32_t len)876 void HdmiCecEncodingVendorCommandMsg(struct HdmiCecMsg *msg, uint8_t *data, uint32_t len)
877 {
878     uint32_t length;
879 
880     if (data == NULL || len == 0) {
881         HDF_LOGE("encoding vendor cmd, input param invalid.");
882         return;
883     }
884     length = (len > HDMI_CEC_VENDOR_SPECIFIC_DATA_MAX_LEN) ? HDMI_CEC_VENDOR_SPECIFIC_DATA_MAX_LEN : len;
885     msg->len = HDMI_CEC_GET_MSG_LEN(length);
886     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_VENDOR_COMMAND;
887     if (memcpy_s(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]), (msg->len - HDMI_CEC_MSG_MIN_LEN), data, length)
888         != EOK) {
889         HDF_LOGE("encoding vendor cmd, memcpy_s fail.");
890     }
891 }
892 
HdmiCecEncodingVendorCommandWithIdMsg(struct HdmiCecMsg * msg,uint32_t vendorId,uint8_t * data,uint32_t len)893 void HdmiCecEncodingVendorCommandWithIdMsg(struct HdmiCecMsg *msg, uint32_t vendorId, uint8_t *data, uint32_t len)
894 {
895     uint32_t length;
896 
897     if (data == NULL || len == 0) {
898         HDF_LOGE("encoding vendor cmd with id, input param invalid.");
899         return;
900     }
901     length = (len > HDMI_CEC_VENDOR_SPECIFIC_DATA_WITH_ID_MAX_LEN) ?
902         HDMI_CEC_VENDOR_SPECIFIC_DATA_WITH_ID_MAX_LEN : len;
903     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_VENDOR_ID_LEN + length);
904     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_VENDOR_COMMAND_WITH_ID;
905     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (vendorId >> HDMI_TWO_BYTES_SHIFT) & HDMI_ONE_BYTE_MARK;
906     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (vendorId >> HDMI_ONE_BYTE_SHIFT) & HDMI_ONE_BYTE_MARK;
907     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = (vendorId & HDMI_ONE_BYTE_MARK);
908     if (memcpy_s(&(msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT]), (msg->len - HDMI_CEC_MSG_DATA_FIFTH_ELEMENT),
909         data, length) != EOK) {
910         HDF_LOGE("encoding vendor cmd with id, memcpy_s fail.");
911     }
912 }
913 
HdmiCecEncodingVendorRemoteButtonDownMsg(struct HdmiCecMsg * msg,uint8_t * rcCode,uint32_t len)914 void HdmiCecEncodingVendorRemoteButtonDownMsg(struct HdmiCecMsg *msg, uint8_t *rcCode, uint32_t len)
915 {
916     uint32_t length;
917 
918     if (rcCode == NULL || len == 0) {
919         HDF_LOGE("encoding vendor remote button down, input param invalid.");
920         return;
921     }
922     length = (len > HDMI_CEC_VENDOR_SPECIFIC_RC_CODE_MAX_LEN) ? HDMI_CEC_VENDOR_SPECIFIC_RC_CODE_MAX_LEN : len;
923     msg->len = HDMI_CEC_GET_MSG_LEN(length);
924     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_VENDOR_REMOTE_BUTTON_DOWN;
925     if (memcpy_s(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]), (msg->len - HDMI_CEC_MSG_DATA_SECOND_ELEMENT),
926         rcCode, length) != EOK) {
927         HDF_LOGE("encoding vendor remote button down, memcpy_s fail.");
928     }
929 }
930 
HdmiCecEncodingVendorRemoteButtonUpMsg(struct HdmiCecMsg * msg)931 void HdmiCecEncodingVendorRemoteButtonUpMsg(struct HdmiCecMsg *msg)
932 {
933     msg->len = HDMI_CEC_GET_MSG_LEN(0);
934     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_VENDOR_REMOTE_BUTTON_UP;
935 }
936 
HdmiCecEncodingSetOsdStringMsg(struct HdmiCecMsg * msg,uint8_t dispControl,uint8_t * str,uint32_t len)937 void HdmiCecEncodingSetOsdStringMsg(struct HdmiCecMsg *msg, uint8_t dispControl, uint8_t *str, uint32_t len)
938 {
939     uint32_t length;
940 
941     if (str == NULL || len == 0) {
942         HDF_LOGE("encoding set OSD string, input param invalid.");
943         return;
944     }
945     length = (len > HDMI_CEC_OSD_STRING_MAX_LEN) ? HDMI_CEC_OSD_STRING_MAX_LEN : len;
946     msg->len = HDMI_CEC_GET_MSG_LEN(length + HDMI_CEC_DISPLAY_CONTROL_LEN);
947     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_OSD_STRING;
948     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = dispControl;
949     if (memcpy_s(&(msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT]), (msg->len - HDMI_CEC_MSG_DATA_THIRD_ELEMENT),
950         str, length) != EOK) {
951         HDF_LOGE("encoding set OSD string, memcpy_s fail.");
952     }
953 }
954 
HdmiCecEncodingGiveOsdNameMsg(struct HdmiCecMsg * msg,bool response)955 void HdmiCecEncodingGiveOsdNameMsg(struct HdmiCecMsg *msg, bool response)
956 {
957     msg->len = HDMI_CEC_GET_MSG_LEN(0);
958     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_OSD_NAME;
959     if (response == true) {
960         msg->rspMsg = HDMI_CEC_OPCODE_SET_OSD_NAME;
961     }
962 }
963 
HdmiCecEncodingSetOsdNameMsg(struct HdmiCecMsg * msg,uint8_t * name,uint32_t len)964 static void HdmiCecEncodingSetOsdNameMsg(struct HdmiCecMsg *msg, uint8_t *name, uint32_t len)
965 {
966     uint32_t length;
967 
968     if (name == NULL || len == 0) {
969         HDF_LOGE("encoding set OSD name, input param invalid.");
970         return;
971     }
972     length = (len > HDMI_CEC_OSD_NAME_MAX_LEN) ? HDMI_CEC_OSD_NAME_MAX_LEN : len;
973     msg->len = HDMI_CEC_GET_MSG_LEN(length);
974     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_OSD_NAME;
975     if (memcpy_s(&(msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT]), (msg->len - HDMI_CEC_MSG_DATA_SECOND_ELEMENT),
976         name, length) != EOK) {
977         HDF_LOGE("encoding set OSD name, memcpy_s fail.");
978     }
979 }
980 
HdmiCecEncodingMenuRequestMsg(struct HdmiCecMsg * msg,uint8_t menuReq,bool response)981 void HdmiCecEncodingMenuRequestMsg(struct HdmiCecMsg *msg, uint8_t menuReq, bool response)
982 {
983     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_MENU_REQUEST_MSG_PARAM_LEN);
984     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_MENU_REQUEST;
985     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = menuReq;
986     if (response == true) {
987         msg->rspMsg = HDMI_CEC_OPCODE_MENU_STATUS;
988     }
989 }
990 
HdmiCecEncodingMenuStatusMsg(struct HdmiCecMsg * msg,uint8_t menuStatus)991 void HdmiCecEncodingMenuStatusMsg(struct HdmiCecMsg *msg, uint8_t menuStatus)
992 {
993     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_MENU_STATUS_MSG_PARAM_LEN);
994     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_MENU_STATUS;
995     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = menuStatus;
996 }
997 
HdmiCecEncodingUserControlPrtessedMsg(struct HdmiCecMsg * msg,const struct HdmiCecUiCmd * cmd)998 void HdmiCecEncodingUserControlPrtessedMsg(struct HdmiCecMsg *msg, const struct HdmiCecUiCmd *cmd)
999 {
1000     if (cmd == NULL) {
1001         return;
1002     }
1003     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_UI_COMMAND_LEN);
1004     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_USER_CONTROL_PRESSED;
1005     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = cmd->cmdType;
1006     if (cmd->hasAddOp == false) {
1007         return;
1008     }
1009     switch (cmd->cmdType) {
1010         case HDMI_CEC_UI_CMD_SELECT_BROADCAST_TYPE:
1011         case HDMI_CEC_UI_CMD_SELECT_SOUND_PRESENTATION:
1012         case HDMI_CEC_UI_CMD_PLAY_FUNCTION:
1013         case HDMI_CEC_UI_CMD_SELECT_MEDIA_FUNCTION:
1014         case HDMI_CEC_UI_CMD_SELECT_AV_INPUT_FUNCTION:
1015         case HDMI_CEC_UI_CMD_SELECT_AUDIO_INPUT_FUNCTION:
1016             (msg->len)++;
1017             /* The additional operand is one byte for all these UI commands */
1018             msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = cmd->addOperands.uiBroadcastType;
1019             break;
1020         case HDMI_CEC_UI_CMD_TUNE_FUNCTION:
1021             msg->len += HDMI_CEC_CHANNEL_IDENTIFIER_LEN;
1022             msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (cmd->addOperands.channel.format <<
1023                                                           HDMI_CEC_CHANNEL_NUMBER_FORMAT_SHIFT) |
1024                                                          (cmd->addOperands.channel.major >> HDMI_ONE_BYTE_SHIFT);
1025             msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = (cmd->addOperands.channel.major & HDMI_ONE_BYTE_MARK);
1026             msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (cmd->addOperands.channel.minor >> HDMI_ONE_BYTE_SHIFT);
1027             msg->data[HDMI_CEC_MSG_DATA_SIXTH_ELEMENT] = (cmd->addOperands.channel.minor & HDMI_ONE_BYTE_MARK);
1028             break;
1029         default:
1030             HDF_LOGI("UI type %d have no additional operands.", cmd->cmdType);
1031             break;
1032     }
1033 }
1034 
HdmiCecEncodingUserControlReleasedMsg(struct HdmiCecMsg * msg)1035 void HdmiCecEncodingUserControlReleasedMsg(struct HdmiCecMsg *msg)
1036 {
1037     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1038     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_USER_CONTROL_RELEASED;
1039 }
1040 
HdmiCecEncodingGiveDevicePowerStatusMsg(struct HdmiCecMsg * msg,bool response)1041 void HdmiCecEncodingGiveDevicePowerStatusMsg(struct HdmiCecMsg *msg, bool response)
1042 {
1043     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1044     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_DEVICE_POWER_STATUS;
1045     if (response == true) {
1046         msg->rspMsg = HDMI_CEC_OPCODE_REPORT_POWER_STATUS;
1047     }
1048 }
1049 
HdmiCecEncodingReportDevicePowerStatusMsg(struct HdmiCecMsg * msg,uint8_t powerStatus)1050 void HdmiCecEncodingReportDevicePowerStatusMsg(struct HdmiCecMsg *msg, uint8_t powerStatus)
1051 {
1052     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_POWER_STATUS_MSG_PARA_LEN);
1053     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REPORT_POWER_STATUS;
1054     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = powerStatus;
1055 }
1056 
HdmiCecEncodingFeatureAbortMsg(struct HdmiCecMsg * msg,uint8_t opcode,uint8_t reason)1057 static void HdmiCecEncodingFeatureAbortMsg(struct HdmiCecMsg *msg, uint8_t opcode, uint8_t reason)
1058 {
1059     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_FEATURE_ABORT_MSG_PARA_LEN);
1060     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_FEATURE_ABORT;
1061     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = opcode;
1062     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = reason;
1063 }
1064 
HdmiCecEncodingAbortMsg(struct HdmiCecMsg * msg)1065 void HdmiCecEncodingAbortMsg(struct HdmiCecMsg *msg)
1066 {
1067     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1068     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_ABORT;
1069 }
1070 
HdmiCecEncodingGiveAudioStatusMsg(struct HdmiCecMsg * msg,bool response)1071 void HdmiCecEncodingGiveAudioStatusMsg(struct HdmiCecMsg *msg, bool response)
1072 {
1073     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1074     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_AUDIO_STATUS;
1075     if (response == true) {
1076         msg->rspMsg = HDMI_CEC_OPCODE_REPORT_AUDIO_STATUS;
1077     }
1078 }
1079 
HdmiCecEncodingGiveSystemAudioModeMsg(struct HdmiCecMsg * msg,bool response)1080 void HdmiCecEncodingGiveSystemAudioModeMsg(struct HdmiCecMsg *msg, bool response)
1081 {
1082     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1083     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_GIVE_SYSTEM_AUDIO_MODE_STATUS;
1084     if (response == true) {
1085         msg->rspMsg = HDMI_CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS;
1086     }
1087 }
1088 
HdmiCecEncodingReportAudioStatusMsg(struct HdmiCecMsg * msg,uint8_t audioMuteStatus,uint8_t audioVolumeStatus)1089 void HdmiCecEncodingReportAudioStatusMsg(struct HdmiCecMsg *msg, uint8_t audioMuteStatus, uint8_t audioVolumeStatus)
1090 {
1091     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_AUDIO_STATUSMSG_PARAM_LEN);
1092     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REPORT_AUDIO_STATUS;
1093     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (audioMuteStatus << HDMI_CEC_AUDIO_MUTE_STATUS_SHIFT) |
1094                                                   (audioVolumeStatus & HDMI_CEC_AUDIO_VOLUME_STATUS_MARK);
1095 }
1096 
HdmiCecEncodingRequestShortAudioDescriptorMsg(struct HdmiCecMsg * msg,const uint8_t * id,const uint8_t * code,uint32_t len,bool response)1097 void HdmiCecEncodingRequestShortAudioDescriptorMsg(struct HdmiCecMsg *msg,
1098     const uint8_t *id, const uint8_t *code, uint32_t len, bool response)
1099 {
1100     uint32_t num;
1101     uint32_t i;
1102 
1103     if (id == NULL || code == NULL || len == 0) {
1104         HDF_LOGE("encoding request short audio descriptor, input param invalid.");
1105         return;
1106     }
1107     num = (len > HDMI_CEC_MAX_AUDIO_FORMAT_NUM) ? HDMI_CEC_MAX_AUDIO_FORMAT_NUM : len;
1108     msg->len = HDMI_CEC_GET_MSG_LEN(num * HDMI_CEC_AUDIO_FORMAT_LEN);
1109     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REQUEST_SHORT_AUDIO_DESCRIPTOR;
1110     for (i = 0; i < num; i++) {
1111         msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT + i] = (id[i] << HDMI_CEC_AUDIO_FORMAT_ID_SHIFT) |
1112             (code[i] & HDMI_CEC_AUDIO_FORMAT_CODE_MARK);
1113     }
1114     if (response == true) {
1115         msg->rspMsg = HDMI_CEC_OPCODE_REPORT_SHORT_AUDIO_DESCRIPTOR;
1116     }
1117 }
1118 
HdmiCecEncodingReportShortAudioDescriptorMsg(struct HdmiCecMsg * msg,const uint32_t * descriptor,uint32_t len)1119 void HdmiCecEncodingReportShortAudioDescriptorMsg(struct HdmiCecMsg *msg, const uint32_t *descriptor, uint32_t len)
1120 {
1121     uint32_t num;
1122     uint32_t i;
1123 
1124     if (descriptor == NULL || len == 0) {
1125         HDF_LOGE("encoding report short audio descriptor, input param invalid.");
1126         return;
1127     }
1128     num = (len > HDMI_CEC_MAX_SHORT_AUDIO_DESCRIPTOR_NUM) ? HDMI_CEC_MAX_SHORT_AUDIO_DESCRIPTOR_NUM : len;
1129     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SHORT_AUDIO_DESCRIPTOR_LEN * num);
1130     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REPORT_SHORT_AUDIO_DESCRIPTOR;
1131     for (i = 0; i < num; i++) {
1132         msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT + i * HDMI_CEC_SHORT_AUDIO_DESCRIPTOR_LEN] =
1133             (descriptor[i] >> HDMI_TWO_BYTES_SHIFT) & HDMI_ONE_BYTE_MARK;
1134         msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT + i * HDMI_CEC_SHORT_AUDIO_DESCRIPTOR_LEN] =
1135             (descriptor[i] >> HDMI_ONE_BYTE_SHIFT) & HDMI_ONE_BYTE_MARK;
1136         msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT + i * HDMI_CEC_SHORT_AUDIO_DESCRIPTOR_LEN] =
1137             descriptor[i] & HDMI_ONE_BYTE_MARK;
1138     }
1139 }
1140 
HdmiCecEncodingSetSystemAudioModeMsg(struct HdmiCecMsg * msg,uint8_t status)1141 void HdmiCecEncodingSetSystemAudioModeMsg(struct HdmiCecMsg *msg, uint8_t status)
1142 {
1143     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SYSTEM_AUDIO_STATUS_LEN);
1144     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_SYSTEM_AUDIO_MODE;
1145     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = status;
1146 }
1147 
HdmiCecEncodingSystemAudioModeRequestMsg(struct HdmiCecMsg * msg,uint16_t phyAddr,bool response)1148 void HdmiCecEncodingSystemAudioModeRequestMsg(struct HdmiCecMsg *msg, uint16_t phyAddr, bool response)
1149 {
1150     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SYSTEM_AUDIO_MODE_REQUEST_PARAM_LEN);
1151     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST;
1152     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
1153     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
1154     if (response == true) {
1155         msg->rspMsg = HDMI_CEC_OPCODE_SET_SYSTEM_AUDIO_MODE;
1156     }
1157 }
1158 
HdmiCecEncodingSystemAudioModeStatusMsg(struct HdmiCecMsg * msg,uint8_t status)1159 void HdmiCecEncodingSystemAudioModeStatusMsg(struct HdmiCecMsg *msg, uint8_t status)
1160 {
1161     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SYSTEM_AUDIO_STATUS_LEN);
1162     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SYSTEM_AUDIO_MODE_STATUS;
1163     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = status;
1164 }
1165 
HdmiCecEncodingSetAudioRateMsg(struct HdmiCecMsg * msg,uint8_t rate)1166 void HdmiCecEncodingSetAudioRateMsg(struct HdmiCecMsg *msg, uint8_t rate)
1167 {
1168     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_SET_AUDIO_RATE_PARAM_LEN);
1169     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_SET_AUDIO_RATE;
1170     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = rate;
1171 }
1172 
HdmiCecEncodingInitiateArcMsg(struct HdmiCecMsg * msg,bool response)1173 void HdmiCecEncodingInitiateArcMsg(struct HdmiCecMsg *msg, bool response)
1174 {
1175     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1176     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_INITIATE_ARC;
1177     if (response == true) {
1178         msg->rspMsg = HDMI_CEC_OPCODE_REPORT_ARC_INITIATED;
1179     }
1180 }
1181 
HdmiCecEncodingReportArcInitiatedMsg(struct HdmiCecMsg * msg)1182 void HdmiCecEncodingReportArcInitiatedMsg(struct HdmiCecMsg *msg)
1183 {
1184     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1185     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REPORT_ARC_INITIATED;
1186 }
1187 
HdmiCecEncodingReportArcTerminationMsg(struct HdmiCecMsg * msg)1188 void HdmiCecEncodingReportArcTerminationMsg(struct HdmiCecMsg *msg)
1189 {
1190     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1191     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REPORT_ARC_TERMINATION;
1192 }
1193 
HdmiCecEncodingRequestArcInitiationMsg(struct HdmiCecMsg * msg,bool response)1194 void HdmiCecEncodingRequestArcInitiationMsg(struct HdmiCecMsg *msg, bool response)
1195 {
1196     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1197     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REQUEST_ARC_INITIATION;
1198     if (response == true) {
1199         msg->rspMsg = HDMI_CEC_OPCODE_INITIATE_ARC;
1200     }
1201 }
1202 
HdmiCecEncodingRequestArcTerminationMsg(struct HdmiCecMsg * msg,bool response)1203 void HdmiCecEncodingRequestArcTerminationMsg(struct HdmiCecMsg *msg, bool response)
1204 {
1205     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1206     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REQUEST_ARC_TERMINATION;
1207     if (response == true) {
1208         msg->rspMsg = HDMI_CEC_OPCODE_TERMINATE_ARC;
1209     }
1210 }
1211 
HdmiCecEncodingTerminateArcMsg(struct HdmiCecMsg * msg,bool response)1212 void HdmiCecEncodingTerminateArcMsg(struct HdmiCecMsg *msg, bool response)
1213 {
1214     msg->len = HDMI_CEC_GET_MSG_LEN(0);
1215     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_TERMINATE_ARC;
1216     if (response == true) {
1217         msg->rspMsg = HDMI_CEC_OPCODE_REPORT_ARC_TERMINATION;
1218     }
1219 }
1220 
HdmiCecEncodingRequestCurrentLatencyMsg(struct HdmiCecMsg * msg,uint16_t phyAddr,bool response)1221 void HdmiCecEncodingRequestCurrentLatencyMsg(struct HdmiCecMsg *msg, uint16_t phyAddr, bool response)
1222 {
1223     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REQUEST_CURRENT_LATENCY_MSG_LEN);
1224     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1225     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REQUEST_CURRENT_LATENCY;
1226     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
1227     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
1228     if (response == true) {
1229         msg->rspMsg = HDMI_CEC_OPCODE_REPORT_CURRENT_LATENCY;
1230     }
1231 }
1232 
HdmiCecEncodingReportCurrentLatencyMsg(struct HdmiCecMsg * msg,uint16_t phyAddr,struct HdmiCecLatencyInfo * info)1233 void HdmiCecEncodingReportCurrentLatencyMsg(struct HdmiCecMsg *msg,
1234     uint16_t phyAddr, struct HdmiCecLatencyInfo *info)
1235 {
1236     msg->len = HDMI_CEC_GET_MSG_LEN(HDMI_CEC_REPORT_CURRENT_LATENCY_MSG_PARAM_MIN_LEN);
1237     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1238     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_REPORT_CURRENT_LATENCY;
1239     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
1240     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
1241     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = info->videoLatency;
1242     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (info->lowLatencyMode << HDMI_CEC_LOW_LATENCY_MODE_SHIFT) |
1243                                                  (info->audioOutputCompensated);
1244     /* Operand[Audio Output Delay] is only present when [Audio Output Compensated] is 3. */
1245     if (info->audioOutputCompensated == HDMI_CEC_AUDIO_OUTPUT_COMPENSATED_PARTIAL_DELAY) {
1246         msg->len++;
1247         msg->data[HDMI_CEC_MSG_DATA_SIXTH_ELEMENT] = info->audioOutputDelay;
1248     }
1249 }
1250 
1251 /* CDC Message Encoding. */
HdmiCdcEncodingHecInquireStateMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr,uint16_t phyAddr1,uint16_t phyAddr2,bool response)1252 void HdmiCdcEncodingHecInquireStateMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr,
1253     uint16_t phyAddr1, uint16_t phyAddr2, bool response)
1254 {
1255     msg->len = HDMI_CDC_GET_MSG_LEN(HDMI_CDC_HEC_INQUIRE_STATE_MSG_PARAM_LEN);
1256     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1257     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1258     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1259     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1260     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CDC_HEC_INQUIRE_STATE;
1261     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (phyAddr1 >> HDMI_ONE_BYTE_SHIFT);
1262     msg->data[HDMI_CEC_MSG_DATA_SIXTH_ELEMENT] = (phyAddr1 & HDMI_ONE_BYTE_MARK);
1263     msg->data[HDMI_CEC_MSG_DATA_SEVENTH_ELEMENT] = (phyAddr2 >> HDMI_ONE_BYTE_SHIFT);
1264     msg->data[HDMI_CEC_MSG_DATA_EIGHTH_ELEMENT] = (phyAddr2 & HDMI_ONE_BYTE_MARK);
1265     if (response == true) {
1266         msg->rspMsg = HDMI_CDC_HEC_REPORT_STATE;
1267     }
1268 }
1269 
HdmiCdcEncodingHecReportStateMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr,uint16_t phyAddr,const struct HdmiCdcHecState * state)1270 void HdmiCdcEncodingHecReportStateMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr,
1271     uint16_t phyAddr, const struct HdmiCdcHecState *state)
1272 {
1273     msg->len = HDMI_CDC_GET_MSG_LEN(HDMI_CDC_HEC_REPORT_STATE_MSG_PARAM_MIN_LEN);
1274     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1275     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1276     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1277     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1278     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CDC_HEC_REPORT_STATE;
1279     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
1280     msg->data[HDMI_CEC_MSG_DATA_SIXTH_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
1281     msg->data[HDMI_CEC_MSG_DATA_SEVENTH_ELEMENT] = (state->hecFuncState << HDMI_CDC_HEC_FUNC_STATE_SHIFT) |
1282                                                    (state->hostFuncState << HDMI_CDC_HOST_FUNC_STATE_SHIFT) |
1283                                                    (state->encFuncState << HDMI_CDC_ENC_FUNC_STATE_SHIFT) |
1284                                                    (state->cdcErrCode);
1285     if (state->haveHecField == true) {
1286         msg->len = HDMI_CDC_GET_MSG_LEN(HDMI_CDC_HEC_REPORT_STATE_MSG_PARAM_MAX_LEN);
1287         msg->data[HDMI_CEC_MSG_DATA_EIGHTH_ELEMENT] = (state->hecField >> HDMI_ONE_BYTE_SHIFT);
1288         msg->data[DATA_NINTH_OFFSET_ELEMENT] = (state->hecField & HDMI_ONE_BYTE_MARK);
1289     }
1290 }
1291 
HdmiCdcEncodingHecSetStateAdjacentMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr,uint16_t phyAddr,uint8_t hecSetState,bool response)1292 void HdmiCdcEncodingHecSetStateAdjacentMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr,
1293     uint16_t phyAddr, uint8_t hecSetState, bool response)
1294 {
1295     msg->len = HDMI_CDC_GET_MSG_LEN(HDMI_CDC_HEC_SET_STATE_ADJACENT_MSG_PARAM_LEN);
1296     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1297     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1298     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1299     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1300     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CDC_HEC_SET_STATE_ADJACENT;
1301     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (phyAddr >> HDMI_ONE_BYTE_SHIFT);
1302     msg->data[HDMI_CEC_MSG_DATA_SIXTH_ELEMENT] = (phyAddr & HDMI_ONE_BYTE_MARK);
1303     msg->data[HDMI_CEC_MSG_DATA_SEVENTH_ELEMENT] = hecSetState;
1304     if (response == true) {
1305         msg->rspMsg = HDMI_CDC_HEC_REPORT_STATE;
1306     }
1307 }
1308 
HdmiCdcEncodingHecSetStateMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr,struct HemiCdcHecStateInfo * info,bool response)1309 void HdmiCdcEncodingHecSetStateMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr,
1310     struct HemiCdcHecStateInfo *info, bool response)
1311 {
1312     uint32_t i;
1313 
1314     msg->len = HDMI_CDC_GET_MSG_LEN(HDMI_CDC_HEC_SET_STATE_MSG_MIN_LEN);
1315     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1316     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1317     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1318     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1319     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CDC_HEC_SET_STATE;
1320     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (info->phyAddr1 >> HDMI_ONE_BYTE_SHIFT);
1321     msg->data[HDMI_CEC_MSG_DATA_SIXTH_ELEMENT] = (info->phyAddr1 & HDMI_ONE_BYTE_MARK);
1322     msg->data[HDMI_CEC_MSG_DATA_SEVENTH_ELEMENT] = (info->phyAddr2 >> HDMI_ONE_BYTE_SHIFT);
1323     msg->data[HDMI_CEC_MSG_DATA_EIGHTH_ELEMENT] = (info->phyAddr2 & HDMI_ONE_BYTE_MARK);
1324     msg->data[DATA_NINTH_OFFSET_ELEMENT] = info->hecSetState;
1325     for (i = 0; (i < info->phyAddrLen) && (i < HDMI_CDC_HEC_SET_STATE_MSG_OPTIONAL_PA_MAX_NUM); i++) {
1326         if (info->phyAddr[i] == HDMI_CEC_INVALID_PHY_ADDR) {
1327             break;
1328         }
1329         msg->data[msg->len] = (info->phyAddr[i] >> HDMI_ONE_BYTE_SHIFT);
1330         (msg->len)++;
1331         msg->data[msg->len] = (info->phyAddr[i] & HDMI_ONE_BYTE_MARK);
1332         (msg->len)++;
1333     }
1334     if (response == true) {
1335         msg->rspMsg = HDMI_CDC_HEC_REPORT_STATE;
1336     }
1337 }
1338 
HdmiCdcEncodingHecRequestDeactivationMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr,const uint16_t * phyAddr,uint32_t len,bool response)1339 void HdmiCdcEncodingHecRequestDeactivationMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr,
1340     const uint16_t *phyAddr, uint32_t len, bool response)
1341 {
1342     uint32_t i;
1343 
1344     if (phyAddr == NULL || len != HDMI_CDC_HEC_REQUEST_DEACTIVATION_MSG_PHY_ADDR_NUM) {
1345         return;
1346     }
1347     msg->len = HDMI_CDC_GET_MSG_LEN(0);
1348     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1349     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1350     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1351     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1352     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CDC_HEC_REQUEST_DEACTIVATION;
1353     for (i = 0; i < len; i++) {
1354         msg->data[msg->len] = (phyAddr[i] >> HDMI_ONE_BYTE_SHIFT);
1355         (msg->len)++;
1356         msg->data[msg->len] = (phyAddr[i] & HDMI_ONE_BYTE_MARK);
1357         (msg->len)++;
1358     }
1359     if (response == true) {
1360         msg->rspMsg = HDMI_CDC_HEC_REPORT_STATE;
1361     }
1362 }
1363 
HdmiCdcEncodingHecNotifyAliveMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr)1364 void HdmiCdcEncodingHecNotifyAliveMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr)
1365 {
1366     msg->len = HDMI_CDC_GET_MSG_LEN(0);
1367     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1368     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1369     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1370     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1371     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CDC_HEC_NOTIFY_ALIVE;
1372 }
1373 
HdmiCdcEncodingHecDiscoverMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr,bool response)1374 void HdmiCdcEncodingHecDiscoverMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr, bool response)
1375 {
1376     msg->len = HDMI_CDC_GET_MSG_LEN(0);
1377     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1378     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1379     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1380     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1381     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CDC_HEC_DISCOVER;
1382     if (response == true) {
1383         msg->rspMsg = HDMI_CDC_HEC_REPORT_STATE;
1384     }
1385 }
1386 
HdmiCdcEncodingHpdSetStateMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr,uint8_t portNum,uint8_t hpdState,bool response)1387 void HdmiCdcEncodingHpdSetStateMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr,
1388     uint8_t portNum, uint8_t hpdState, bool response)
1389 {
1390     msg->len = HDMI_CDC_GET_MSG_LEN(HDMI_CDC_HPD_SET_STATE_MSG_LEN);
1391     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1392     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1393     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1394     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1395     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = HDMI_CDC_HPD_SET_STATE;
1396     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (portNum << HDMI_CDC_INPUT_PORT_NUMBER_SHIFT) | hpdState;
1397     if (response == true) {
1398         msg->rspMsg = CEC_MSG_CDC_HPD_REPORT_STATE;
1399     }
1400 }
1401 
HdmiCdcEncodingHpdReportStateMsg(struct HdmiCecMsg * msg,uint16_t initiatorPhyAddr,uint8_t hpdState,uint8_t errCode)1402 void HdmiCdcEncodingHpdReportStateMsg(struct HdmiCecMsg *msg, uint16_t initiatorPhyAddr,
1403     uint8_t hpdState, uint8_t errCode)
1404 {
1405     msg->len = HDMI_CDC_GET_MSG_LEN(HDMI_CDC_HPD_REPORT_STATE_MSG_LEN);
1406     msg->data[HDMI_CEC_MSG_DATA_ZEROTH_ELEMENT] |= HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST;
1407     msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT] = HDMI_CEC_OPCODE_CDC_MESSAGE;
1408     msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] = (initiatorPhyAddr >> HDMI_ONE_BYTE_SHIFT);
1409     msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT] = (initiatorPhyAddr & HDMI_ONE_BYTE_MARK);
1410     msg->data[HDMI_CEC_MSG_DATA_FORTH_ELEMENT] = CEC_MSG_CDC_HPD_REPORT_STATE;
1411     msg->data[HDMI_CEC_MSG_DATA_FIFTH_ELEMENT] = (hpdState << HDMI_CDC_INPUT_PORT_NUMBER_SHIFT) | errCode;
1412 }
1413 
HdmiCecSendMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg)1414 static int32_t HdmiCecSendMsg(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg)
1415 {
1416     int32_t ret;
1417 
1418     if (cntlr->ops == NULL || cntlr->ops->cecMsgSend == NULL) {
1419         return HDF_ERR_NOT_SUPPORT;
1420     }
1421 
1422     if (msg->response == true) {
1423         msg->timeout = HDMI_CEC_WAIT_RESPONSE_MSG_MAX_TIME;
1424     }
1425 
1426     HdmiCntlrLock(cntlr);
1427     ret = cntlr->ops->cecMsgSend(cntlr, msg);
1428     HdmiCntlrUnlock(cntlr);
1429     return ret;
1430 }
1431 
HdmiCecMsgIgnore(uint8_t opcode,bool unregistered,bool broadcast)1432 static bool HdmiCecMsgIgnore(uint8_t opcode, bool unregistered, bool broadcast)
1433 {
1434     switch (opcode) {
1435         case HDMI_CEC_OPCODE_GET_CEC_VERSION:
1436         case HDMI_CEC_OPCODE_ABORT:
1437         case HDMI_CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
1438         case HDMI_CEC_OPCODE_GIVE_OSD_NAME:
1439             /* Ignore if initiator is Unregistered, because these messages should reply with a directed message. */
1440             if (unregistered == true) {
1441                 return true;
1442             }
1443         /* fallthrough */
1444         case HDMI_CEC_OPCODE_GIVE_DEVICE_VENDOR_ID:
1445         case HDMI_CEC_OPCODE_GIVE_FEATURES:
1446         case HDMI_CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
1447             /* Ignore if addressing is wrong */
1448             if (broadcast == true) {
1449                 return true;
1450             }
1451             break;
1452         case HDMI_CEC_OPCODE_USER_CONTROL_PRESSED:
1453         case HDMI_CEC_OPCODE_USER_CONTROL_RELEASED:
1454             if (unregistered == true || broadcast == true) {
1455                 return true;
1456             }
1457             break;
1458         case HDMI_CEC_OPCODE_REPORT_PHYSICAL_ADDRESS:
1459             if (broadcast == false) {
1460                 return true;
1461             }
1462             break;
1463         default:
1464             break;
1465     }
1466     return false;
1467 }
1468 
HdmiCecHandleReportPhyAddressMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1469 static void HdmiCecHandleReportPhyAddressMsg(struct HdmiCntlr *cntlr,
1470     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1471 {
1472     uint16_t phyAddr;
1473 
1474     phyAddr = ((msg->data[HDMI_CEC_MSG_DATA_SECOND_ELEMENT] << HDMI_ONE_BYTE_SHIFT) |
1475                msg->data[HDMI_CEC_MSG_DATA_THIRD_ELEMENT]);
1476     (void)cntlr;
1477     (void)txMsg;
1478 
1479     HDF_LOGD("reported phy address is  %x.%x.%x.%x, logical address is  %d",
1480         HDMI_CEC_PHY_ADDR_PHASE(phyAddr), HdmiCecGetMsgInitiator(msg));
1481 }
1482 
HdmiCecHandleUserControlPrtessedMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1483 static void HdmiCecHandleUserControlPrtessedMsg(struct HdmiCntlr *cntlr,
1484     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1485 {
1486     (void)msg;
1487     (void)txMsg;
1488 
1489     /* Not support CEC Remote Control. */
1490     if (cntlr->cap.baseCap.bits.cecRc == 0) {
1491         return;
1492     }
1493     HDF_LOGD("Now User Control Prtessed not support.");
1494 }
1495 
HdmiCecHandleUserControlReleasedMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1496 static void HdmiCecHandleUserControlReleasedMsg(struct HdmiCntlr *cntlr,
1497     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1498 {
1499     (void)msg;
1500     (void)txMsg;
1501 
1502     /* Not support CEC Remote Control. */
1503     if (cntlr->cap.baseCap.bits.cecRc == 0) {
1504         return;
1505     }
1506     HDF_LOGD("Now User Control Released not support.");
1507 }
1508 
HdmiCecHandleGetCecVersionMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1509 static void HdmiCecHandleGetCecVersionMsg(struct HdmiCntlr *cntlr,
1510     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1511 {
1512     (void)msg;
1513     HdmiCecEncodingCecVersionMsg(txMsg, cntlr->cec->info.cecVersion);
1514     if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1515         HDF_LOGE("get cec version msg send fail");
1516     }
1517 }
1518 
HdmiCecHandleGivePhyAddressMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1519 static void HdmiCecHandleGivePhyAddressMsg(struct HdmiCntlr *cntlr,
1520     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1521 {
1522     /* Ignore for CEC switches using addr 15. */
1523     if ((cntlr->cec->info.primaryDeviceType == HDMI_CEC_DEVICE_TYPE_PURE_CEC_SWITCH) &&
1524         (HdmiCecGetMsgDestination(msg) == HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST)) {
1525         return;
1526     }
1527 
1528     HdmiCecEncodingReportPhyAddressMsg(txMsg, cntlr->cec->info.phyAddr, cntlr->cec->info.primaryDeviceType);
1529     if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1530         HDF_LOGE("give phy address msg send fail");
1531     }
1532 }
1533 
HdmiCecHandleGiveDeviceVendorIdMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1534 static void HdmiCecHandleGiveDeviceVendorIdMsg(struct HdmiCntlr *cntlr,
1535     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1536 {
1537     if (cntlr->cec->info.vendorId == HDMI_CEC_VENDOR_ID_UNKNOWN) {
1538         HdmiCecEncodingFeatureAbortMsg(txMsg,
1539                                        msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT],
1540                                        HDMI_CEC_ABORT_UNRECOGNIZED_OPCODE);
1541         if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1542             HDF_LOGE("feature abort msg send fail");
1543         }
1544         return;
1545     }
1546     HdmiCecEncodingDeviceVendorIdMsg(txMsg, cntlr->cec->info.vendorId);
1547     if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1548         HDF_LOGE("give device vendor id msg send fail");
1549     }
1550 }
1551 
HdmiCecHandleAbortMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1552 static void HdmiCecHandleAbortMsg(struct HdmiCntlr *cntlr,
1553     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1554 {
1555     /* Ignore for CEC switches. */
1556     if (cntlr->cec->info.primaryDeviceType == HDMI_CEC_DEVICE_TYPE_PURE_CEC_SWITCH) {
1557         return;
1558     }
1559     HdmiCecEncodingFeatureAbortMsg(txMsg, msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT], HDMI_CEC_ABORT_REFUSED);
1560     if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1561         HDF_LOGE("feature abort msg send fail");
1562     }
1563 }
1564 
HdmiCecHandleGiveOsdNameMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1565 static void HdmiCecHandleGiveOsdNameMsg(struct HdmiCntlr *cntlr,
1566     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1567 {
1568     if (cntlr->cec->info.osdName[0] == 0) {
1569         HdmiCecEncodingFeatureAbortMsg(txMsg,
1570                                        msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT],
1571                                        HDMI_CEC_ABORT_UNRECOGNIZED_OPCODE);
1572         if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1573             HDF_LOGE("feature abort msg send fail");
1574         }
1575         return;
1576     }
1577 
1578     HdmiCecEncodingSetOsdNameMsg(txMsg, cntlr->cec->info.osdName, cntlr->cec->info.osdNameLen);
1579     if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1580         HDF_LOGE("set osd name msg send fail");
1581     }
1582 }
1583 
HdmiCecHandleGiveFeaturesMsg(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1584 static void HdmiCecHandleGiveFeaturesMsg(struct HdmiCntlr *cntlr,
1585     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1586 {
1587     if (cntlr->cec->info.cecVersion < HDMI_CEC_VERSION_2_0) {
1588         HdmiCecEncodingFeatureAbortMsg(txMsg,
1589                                        msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT],
1590                                        HDMI_CEC_ABORT_UNRECOGNIZED_OPCODE);
1591         if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1592             HDF_LOGE("feature abort msg send fail");
1593         }
1594         return;
1595     }
1596 
1597     HdmiCecEncodingReportFeaturesMsg(txMsg, &(cntlr->cec->info));
1598     if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1599         HDF_LOGE("report feature msg send fail");
1600     }
1601 }
1602 
HdmiCecMsgDefaultHandle(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg)1603 static void HdmiCecMsgDefaultHandle(struct HdmiCntlr *cntlr,
1604     struct HdmiCecMsg *msg, struct HdmiCecMsg *txMsg)
1605 {
1606     bool broadcast = HdmiCecIsBroadcastMsg(msg);
1607     uint8_t opcode = msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT];
1608     bool isResponse = (cntlr->cec->info.isWaitingResponse == true && cntlr->cec->info.response == opcode);
1609 
1610     if (broadcast == true || isResponse == true) {
1611         return;
1612     }
1613     if (opcode != HDMI_CEC_OPCODE_FEATURE_ABORT) {
1614         return;
1615     }
1616 
1617     HdmiCecEncodingFeatureAbortMsg(txMsg, opcode, HDMI_CEC_ABORT_UNRECOGNIZED_OPCODE);
1618     if (HdmiCecSendMsg(cntlr, txMsg) != HDF_SUCCESS) {
1619         HDF_LOGE("feature abort msg send fail");
1620     }
1621 }
1622 
HdmiCecMsgHandle(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg,struct HdmiCecMsg * txMsg,uint8_t opcode)1623 static void HdmiCecMsgHandle(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg,
1624     struct HdmiCecMsg *txMsg, uint8_t opcode)
1625 {
1626     uint32_t i;
1627     uint32_t len;
1628 
1629     struct HdmiCecHandleMsgFuncMap funcMap[] = {
1630         { HDMI_CEC_OPCODE_GET_CEC_VERSION, HdmiCecHandleGetCecVersionMsg },
1631         { HDMI_CEC_OPCODE_REPORT_PHYSICAL_ADDRESS, HdmiCecHandleReportPhyAddressMsg },
1632         { HDMI_CEC_OPCODE_USER_CONTROL_PRESSED, HdmiCecHandleUserControlPrtessedMsg },
1633         { HDMI_CEC_OPCODE_USER_CONTROL_RELEASED, HdmiCecHandleUserControlReleasedMsg },
1634         { HDMI_CEC_OPCODE_GIVE_PHYSICAL_ADDRESS, HdmiCecHandleGivePhyAddressMsg },
1635         { HDMI_CEC_OPCODE_GIVE_DEVICE_VENDOR_ID, HdmiCecHandleGiveDeviceVendorIdMsg },
1636         { HDMI_CEC_OPCODE_ABORT, HdmiCecHandleAbortMsg },
1637         { HDMI_CEC_OPCODE_GIVE_OSD_NAME, HdmiCecHandleGiveOsdNameMsg },
1638         { HDMI_CEC_OPCODE_GIVE_FEATURES, HdmiCecHandleGiveFeaturesMsg }
1639     };
1640 
1641     len = sizeof(funcMap) / sizeof(funcMap[0]);
1642     for (i = 0; i < len; i++) {
1643         if (opcode == funcMap[i].opcode) {
1644             funcMap[i].func(cntlr, msg, txMsg);
1645             return;
1646         }
1647     }
1648     HdmiCecMsgDefaultHandle(cntlr, msg, txMsg);
1649 }
1650 
HdmiCecUpdateResponseFlag(struct HdmiCec * cec,uint8_t opcode)1651 static void HdmiCecUpdateResponseFlag(struct HdmiCec *cec, uint8_t opcode)
1652 {
1653     /* receive response msg. */
1654     if (cec->info.isWaitingResponse == true && cec->info.response == opcode) {
1655         cec->info.isWaitingResponse = false;
1656         cec->info.response = 0;
1657     }
1658 }
1659 
HdmiCecReceivedMsgHandle(struct HdmiCntlr * cntlr,struct HdmiCecMsg * msg)1660 static void HdmiCecReceivedMsgHandle(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg)
1661 {
1662     uint8_t opcode = msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT];
1663     bool broadcast = HdmiCecIsBroadcastMsg(msg);
1664     bool unregistered = (HdmiCecGetMsgInitiator(msg) == HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST);
1665     struct HdmiCecMsg txMsg = {0};
1666 
1667     if (HdmiCecMsgIgnore(opcode, unregistered, broadcast) == true) {
1668         HdmiCecUpdateResponseFlag(cntlr->cec, opcode);
1669         return;
1670     }
1671 
1672     HdmiCecFillMsgHeader(&txMsg, msg);
1673     HdmiCecMsgHandle(cntlr, msg, &txMsg, opcode);
1674     HdmiCecUpdateResponseFlag(cntlr->cec, opcode);
1675 }
1676 
HdmiCecReceivedMsg(struct HdmiCec * cec,struct HdmiCecMsg * msg)1677 int32_t HdmiCecReceivedMsg(struct HdmiCec *cec, struct HdmiCecMsg *msg)
1678 {
1679     struct HdmiCntlr *cntlr = NULL;
1680     uint8_t opcode;
1681     uint8_t initiator;
1682     uint8_t destination;
1683 
1684     if (cec == NULL || cec->priv == NULL || msg == NULL) {
1685         HDF_LOGE("cec receive msg, input param invalid.");
1686         return HDF_ERR_INVALID_PARAM;
1687     }
1688 
1689     cntlr = (struct HdmiCntlr *)cec->priv;
1690     if (cntlr->cap.baseCap.bits.cec == 0) {
1691         HDF_LOGD("not support cec.");
1692         return HDF_ERR_NOT_SUPPORT;
1693     }
1694 
1695     if (msg->len < HDMI_CEC_MSG_MIN_LEN) {
1696         HDF_LOGE("cec receive msg, len is error.");
1697         return HDF_ERR_INVALID_PARAM;
1698     }
1699 
1700     initiator = HdmiCecGetMsgInitiator(msg);
1701     destination = HdmiCecGetMsgDestination(msg);
1702     opcode = msg->data[HDMI_CEC_MSG_DATA_FIRST_ELEMENT];
1703     /* Check if this message is for us. */
1704     if ((initiator != HDMI_CEC_LOG_ADDR_UNREGISTERED_OR_BROADCAST) &&
1705         (HdmiCecLogAddrValid(cntlr->cec, initiator) == true)) {
1706         return HDF_ERR_INVALID_PARAM;
1707     }
1708     if ((HdmiCecIsBroadcastMsg(msg) == false) &&
1709         (HdmiCecLogAddrValid(cec, destination) == false)) {
1710         HDF_LOGD("this cec msg is not for us!");
1711         return HDF_ERR_INVALID_PARAM;
1712     }
1713 
1714     if (cntlr->cec->info.logAddrMask == 0) {
1715         return HDF_ERR_NOT_SUPPORT;
1716     }
1717 
1718     /* CDC Only devices should ignore non-CDC messages. */
1719     if ((HdmiCecIsCdcOnlyDevice(cec) == true) &&
1720         (opcode != HDMI_CEC_OPCODE_CDC_MESSAGE)) {
1721         HDF_LOGD("this cec msg is not cdc msg.");
1722         return HDF_ERR_NOT_SUPPORT;
1723     }
1724     if (HdmiCecCheckMsgLen(cec, msg, opcode) == false) {
1725         return HDF_ERR_INVALID_PARAM;
1726     }
1727 
1728     HdmiCecReceivedMsgHandle(cntlr, msg);
1729     return HDF_SUCCESS;
1730 }
1731