aboutsummaryrefslogtreecommitdiffstats
path: root/lib/igt_chamelium.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/igt_chamelium.c')
-rw-r--r--lib/igt_chamelium.c101
1 files changed, 99 insertions, 2 deletions
diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index 301e9d21..1b03a103 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -351,6 +351,32 @@ static xmlrpc_value *chamelium_rpc(struct chamelium *chamelium,
return res;
}
+static bool __chamelium_is_reachable(struct chamelium *chamelium)
+{
+ xmlrpc_value *res;
+
+ /* GetSupportedInputs does not require a port and is harmless */
+ res = __chamelium_rpc(chamelium, NULL, "GetSupportedInputs", "()");
+
+ if (res != NULL)
+ xmlrpc_DECREF(res);
+
+ if (chamelium->env.fault_occurred)
+ igt_debug("Chamelium RPC call failed: %s\n",
+ chamelium->env.fault_string);
+
+ return !chamelium->env.fault_occurred;
+}
+
+void chamelium_wait_reachable(struct chamelium *chamelium, int timeout)
+{
+ bool chamelium_online = igt_wait(__chamelium_is_reachable(chamelium),
+ timeout * 1000, 100);
+
+ igt_assert_f(chamelium_online,
+ "Couldn't connect to Chamelium for %ds", timeout);
+}
+
/**
* chamelium_plug:
* @chamelium: The Chamelium instance to use
@@ -562,10 +588,9 @@ static void chamelium_destroy_edid(struct chamelium *chamelium, int edid_id)
* Returns: An opaque pointer to the Chamelium EDID
*/
struct chamelium_edid *chamelium_new_edid(struct chamelium *chamelium,
- const unsigned char *raw_edid)
+ const struct edid *edid)
{
struct chamelium_edid *chamelium_edid;
- const struct edid *edid = (struct edid *) raw_edid;
size_t edid_size = edid_get_size(edid);
chamelium_edid = calloc(1, sizeof(struct chamelium_edid));
@@ -1124,6 +1149,78 @@ int chamelium_get_captured_frame_count(struct chamelium *chamelium)
return ret;
}
+bool chamelium_supports_get_last_infoframe(struct chamelium *chamelium)
+{
+ return chamelium_supports_method(chamelium, "GetLastInfoFrame");
+}
+
+static const char *
+chamelium_infoframe_type_str(enum chamelium_infoframe_type type)
+{
+ switch (type) {
+ case CHAMELIUM_INFOFRAME_AVI:
+ return "avi";
+ case CHAMELIUM_INFOFRAME_AUDIO:
+ return "audio";
+ case CHAMELIUM_INFOFRAME_MPEG:
+ return "mpeg";
+ case CHAMELIUM_INFOFRAME_VENDOR:
+ return "vendor";
+ }
+ assert(0); /* unreachable */
+}
+
+struct chamelium_infoframe *
+chamelium_get_last_infoframe(struct chamelium *chamelium,
+ struct chamelium_port *port,
+ enum chamelium_infoframe_type type)
+{
+ xmlrpc_value *res, *res_version, *res_payload;
+ struct chamelium_infoframe *infoframe;
+ const unsigned char *payload;
+
+ res = chamelium_rpc(chamelium, NULL, "GetLastInfoFrame", "(is)",
+ port->id, chamelium_infoframe_type_str(type));
+ xmlrpc_struct_find_value(&chamelium->env, res, "version", &res_version);
+ xmlrpc_struct_find_value(&chamelium->env, res, "payload", &res_payload);
+ infoframe = calloc(1, sizeof(*infoframe));
+ xmlrpc_read_int(&chamelium->env, res_version, &infoframe->version);
+ xmlrpc_read_base64(&chamelium->env, res_payload,
+ &infoframe->payload_size, &payload);
+ /* xmlrpc-c's docs say payload is actually not constant */
+ infoframe->payload = (uint8_t *) payload;
+ xmlrpc_DECREF(res_version);
+ xmlrpc_DECREF(res_payload);
+ xmlrpc_DECREF(res);
+
+ if (infoframe->payload_size == 0) {
+ chamelium_infoframe_destroy(infoframe);
+ return NULL;
+ }
+ return infoframe;
+}
+
+void chamelium_infoframe_destroy(struct chamelium_infoframe *infoframe)
+{
+ free(infoframe->payload);
+ free(infoframe);
+}
+
+bool chamelium_supports_trigger_link_failure(struct chamelium *chamelium)
+{
+ return chamelium_supports_method(chamelium, "TriggerLinkFailure");
+}
+
+/**
+ * chamelium_trigger_link_failure: trigger a link failure on the provided port.
+ */
+void chamelium_trigger_link_failure(struct chamelium *chamelium,
+ struct chamelium_port *port)
+{
+ xmlrpc_DECREF(chamelium_rpc(chamelium, port, "TriggerLinkFailure",
+ "(i)", port->id));
+}
+
bool chamelium_has_audio_support(struct chamelium *chamelium,
struct chamelium_port *port)
{