/* * Reading of kernel events */ void thread_kevent_fn(void *arg) { int event; struct pollfd pollfds; LOGHDMILIB("%s begin", __func__); /* * Note: events are subscribed at call to api function hdmi_enable * Until then no events will occur. */ /* Open the event file */ hdmieventfile_open(&pollfds); while (1) { /* Read poll event file */ event = hdmieventfile_read(pollfds.fd); LOGHDMILIB("kevent:%x", event); if (event == HDMIEVENT_POLLSIZEFAIL) { usleep(100000); /* Close event file */ hdmieventfile_close(pollfds.fd); /* Open the event file */ hdmieventfile_open(&pollfds); } else { /* Signal main thread */ hdmi_event(event); if (event & HDMIEVENT_WAKEUP) break; } /* Poll plug event file */ hdmieventfile_poll(&pollfds); } /* Clear events */ hdmievclr(EVENTMASK_ALL); /* Close event file */ hdmieventfile_close(pollfds.fd); LOGHDMILIB("%s end", __func__); /* Exit thread */ pthread_exit(NULL); }
/* Get current hdcp state */ int hdcp_state(void) { int hdcpstateget; int result = HDCP_OK; int res; __u8 buf[128]; int val; __u32 cmd_id; cmd_id = get_new_cmd_id_ind(); /* Check hdcpstate */ hdcpstateget = open(HDCPSTATEGET_FILE, O_RDONLY); if (hdcpstateget < 0) { LOGHDMILIB("***** Failed to open %s *****", HDCPSTATEGET_FILE); result = SYSFS_FILE_FAILED; goto hdcp_state_end; } res = read(hdcpstateget, buf, sizeof(buf)); close(hdcpstateget); if (res != 1) { LOGHDMILIB("***** %s read error *****", HDCPSTATEGET_FILE); result = HDCPSTATE_FAIL; goto hdcp_state_end; } val = HDMI_HDCPSTATE; memcpy(&buf[CMD_OFFSET], &val, 4); memcpy(&buf[CMDID_OFFSET], &cmd_id, 4); val = 1; memcpy(&buf[CMDLEN_OFFSET], &val, 4); memcpy(&buf[CMDBUF_OFFSET], buf, val); /* Send on socket */ if (clientsocket_send(buf, CMDBUF_OFFSET + val) != 0) result = HDCPSTATE_FAIL; LOGHDMILIB("%s", dbg_hdcpstate(val)); hdcp_state_end: return result; }
/* Read received CEC message and forward on client socket */ int cecrx(void) { int cecreadfd; __u8 buf[32]; __u8 cecdata[32]; int cecsize; int cnt; int val; int res = 0; __u32 cmd_id; LOGHDMILIB("%s begin", __func__); cmd_id = get_new_cmd_id_ind(); cecreadfd = open(CECREAD_FILE, O_RDONLY); if (cecreadfd < 0) { LOGHDMILIBE("***** Failed to open %s *****", CECREAD_FILE); return -1; } cecsize = read(cecreadfd, buf, sizeof(buf)); close(cecreadfd); if (cecsize < 0) return -1; for (cnt = 0; cnt < cecsize; cnt++) LOGHDMILIB2("cecrx[%d]:%x", cnt, buf[cnt]); val = HDMI_CECRECVD; memcpy(&buf[CMD_OFFSET], &val, 4); memcpy(&buf[CMDID_OFFSET], &cmd_id, 4); val = cecsize; memcpy(&buf[CMDLEN_OFFSET], &val, 4); memcpy(&buf[CMDBUF_OFFSET], cecdata, val); /* Send on socket */ res = clientsocket_send(buf, CMDBUF_OFFSET + val); LOGHDMILIB("%s end", __func__); return res; }
/* Send CEC message */ int cecsend(__u32 cmd_id, __u8 in, __u8 dest, __u8 len, __u8 *data) { int cecsendfd; int res; char buf[128]; LOGHDMILIB("%s begin", __func__); cectxcmdid_set(cmd_id); res = 0; buf[0] = in; buf[1] = dest; buf[2] = len; memcpy(&buf[3], data, len); /* Send CEC cmd */ cecsendfd = open(CECSEND_FILE, O_WRONLY); if (cecsendfd <= 0) { LOGHDMILIBE("***** Failed to open %s *****\n", CECSEND_FILE); goto cecsend_err; } res = write(cecsendfd, buf, len + 3); if (res != len + 3) { LOGHDMILIBE("***** cecsend failed %d *****\n", res); close(cecsendfd); goto cecsend_err; } close(cecsendfd); LOGHDMILIB("%s end", __func__); return 0; cecsend_err: cecsenderr(); LOGHDMILIB("%s end", __func__); return -1; }
/* Load aes keys and start hdcp encryption */ int hdcp_init(__u8 *aes) { int hdcpchkaesotp; int hdcploadaes; int hdcpauthencr; int hdcpeven; int res; int value = 0; char buf[128]; int result = HDCP_OK; /* Check if OTP is fused */ hdcpchkaesotp = open(HDCPCHKAESOTP_FILE, O_RDONLY); if (hdcpchkaesotp < 0) { LOGHDMILIB("***** Failed to open %s *****", HDCPCHKAESOTP_FILE); result = SYSFS_FILE_FAILED; goto hdcp_end; } res = read(hdcpchkaesotp, buf, sizeof(buf)); close(hdcpchkaesotp); if (res != 1) { LOGHDMILIB("***** %s read error *****", HDCPCHKAESOTP_FILE); result = SYSFS_FILE_FAILED; goto hdcp_end; } value = *buf; LOGHDMILIB("%s", dbg_otp(value)); if (value == OTP_PROGGED) { /* Subscribe for hdcp events */ hdcpeven = open(HDCPEVEN_FILE, O_WRONLY); if (hdcpeven < 0) { LOGHDMILIB("***** Failed to open %s *****", HDCPEVEN_FILE); result = SYSFS_FILE_FAILED; goto hdcp_end; } res = write(hdcpeven, hdcp_even_val, sizeof(hdcp_even_val)); close(hdcpeven); if (res != sizeof(hdcp_even_val)) { result = SYSFS_FILE_FAILED; goto hdcp_end; } /* Write aes keys */ hdcploadaes = open(HDCPLOADAES_FILE, O_WRONLY); if (hdcploadaes < 0) { LOGHDMILIB("***** Failed to open %s *****", HDCPLOADAES_FILE); result = SYSFS_FILE_FAILED; goto hdcp_end; } res = write(hdcploadaes, aes, AES_KEYS_SIZE); close(hdcploadaes); if (res != AES_KEYS_SIZE) { LOGHDMILIB("***** Failed to write hdcploadaes %d " "*****", res); result = SYSFS_FILE_FAILED; goto hdcp_end; } usleep(LOADAES_WAITTIME); /* Check result */ hdcploadaes = open(HDCPLOADAES_FILE, O_RDONLY); if (hdcploadaes < 0) { LOGHDMILIB("***** Failed to open %s *****", HDCPLOADAES_FILE); result = SYSFS_FILE_FAILED; goto hdcp_end; } res = read(hdcploadaes, buf, sizeof(buf)); close(hdcploadaes); if (res != 1) { LOGHDMILIB("***** %s read error *****", HDCPLOADAES_FILE); result = SYSFS_FILE_FAILED; goto hdcp_end; } value = *buf; LOGHDMILIB("%s", dbg_loadaes(value)); if (value == LOADAES_OK) { LOGHDMILIB("%s", "--- LOAD AES keys OK ---"); } else { result = AESKEYS_FAIL; goto hdcp_end; } usleep(LOADAES_WAITTIME); /* Start HDCP encryption */ hdcpauthencr = open(HDCPAUTH_FILE, O_WRONLY); if (hdcpauthencr < 0) { LOGHDMILIB("***** Failed to open %s *****", HDCPAUTH_FILE); result = HDCPAUTHENCR_FAIL; goto hdcp_end; } res = write(hdcpauthencr, hdcp_encr_start_val, sizeof(hdcp_encr_start_val)); close(hdcpauthencr); if (res != sizeof(hdcp_encr_start_val)) { LOGHDMILIB("***** Failed to write hdcpauthencr %d " "*****", res); result = HDCPAUTHENCR_FAIL; goto hdcp_end; } usleep(HDCPAUTH_WAITTIME); } else { printf("***** Missing aes file or HDCP AES OTP is not fused." " *****\n"); } hdcp_end: return result; }
static int hdmieventfile_close(int fd) { LOGHDMILIB("%s", __func__); close(fd); return 0; }