if (is_hdcp1(hdcp)) {
hdcp->connection.hdcp1_retry_count++;
+ if (hdcp->connection.hdcp1_retry_count == MAX_NUM_OF_ATTEMPTS)
+ hdcp->connection.link.adjust.hdcp1.disable = 1;
} else if (is_hdcp2(hdcp)) {
hdcp->connection.hdcp2_retry_count++;
+ if (hdcp->connection.hdcp2_retry_count == MAX_NUM_OF_ATTEMPTS)
+ hdcp->connection.link.adjust.hdcp2.disable = 1;
}
}
}
}
- return (hdcp->connection.hdcp1_retry_count < MAX_NUM_OF_ATTEMPTS) &&
- is_auth_needed &&
+ return is_auth_needed &&
!hdcp->connection.link.adjust.hdcp1.disable &&
!hdcp->connection.is_hdcp1_revoked;
}
}
}
- return (hdcp->connection.hdcp2_retry_count < MAX_NUM_OF_ATTEMPTS) &&
- is_auth_needed &&
+ return is_auth_needed &&
!hdcp->connection.link.adjust.hdcp2.disable &&
!hdcp->connection.is_hdcp2_revoked;
}
return status;
}
+enum mod_hdcp_status mod_hdcp_update_authentication(struct mod_hdcp *hdcp,
+ uint8_t index,
+ struct mod_hdcp_link_adjustment *link_adjust,
+ struct mod_hdcp_display_adjustment *display_adjust,
+ struct mod_hdcp_output *output)
+{
+ enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
+ struct mod_hdcp_display *display = NULL;
+
+ HDCP_TOP_INTERFACE_TRACE_WITH_INDEX(hdcp, index);
+ memset(output, 0, sizeof(struct mod_hdcp_output));
+
+ /* find display in connection */
+ display = get_active_display_at_index(hdcp, index);
+ if (!display) {
+ status = MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
+ goto out;
+ }
+
+ /* skip if no changes */
+ if (memcmp(link_adjust, &hdcp->connection.link.adjust,
+ sizeof(struct mod_hdcp_link_adjustment)) == 0 &&
+ memcmp(display_adjust, &display->adjust,
+ sizeof(struct mod_hdcp_display_adjustment)) == 0) {
+ status = MOD_HDCP_STATUS_SUCCESS;
+ goto out;
+ }
+
+ /* stop current authentication */
+ status = reset_authentication(hdcp, output);
+ if (status != MOD_HDCP_STATUS_SUCCESS)
+ goto out;
+
+ /* clear retry counters */
+ reset_retry_counts(hdcp);
+
+ /* reset error trace */
+ memset(&hdcp->connection.trace, 0, sizeof(hdcp->connection.trace));
+
+ /* set new adjustment */
+ hdcp->connection.link.adjust = *link_adjust;
+ display->adjust = *display_adjust;
+
+ /* request authentication when connection is not reset */
+ if (current_state(hdcp) != HDCP_UNINITIALIZED)
+ /* wait 100ms to debounce simultaneous updates for different indices */
+ callback_in_ms(100, output);
+
+out:
+ if (status != MOD_HDCP_STATUS_SUCCESS)
+ push_error_status(hdcp, status);
+ return status;
+}
+
enum mod_hdcp_status mod_hdcp_query_display(struct mod_hdcp *hdcp,
uint8_t index, struct mod_hdcp_display_query *query)
{
/* called per link on link destroy */
enum mod_hdcp_status mod_hdcp_teardown(struct mod_hdcp *hdcp);
-/* called per display on cp_desired set to true */
+/* called per display after stream is enabled */
enum mod_hdcp_status mod_hdcp_add_display(struct mod_hdcp *hdcp,
struct mod_hdcp_link *link, struct mod_hdcp_display *display,
struct mod_hdcp_output *output);
-/* called per display on cp_desired set to false */
+/* called per display before stream is disabled */
enum mod_hdcp_status mod_hdcp_remove_display(struct mod_hdcp *hdcp,
uint8_t index, struct mod_hdcp_output *output);
+/* called per display to apply new authentication adjustment */
+enum mod_hdcp_status mod_hdcp_update_authentication(struct mod_hdcp *hdcp,
+ uint8_t index,
+ struct mod_hdcp_link_adjustment *link_adjust,
+ struct mod_hdcp_display_adjustment *display_adjust,
+ struct mod_hdcp_output *output);
+
/* called to query hdcp information on a specific index */
enum mod_hdcp_status mod_hdcp_query_display(struct mod_hdcp *hdcp,
uint8_t index, struct mod_hdcp_display_query *query);