[PATCH 07/25] efw-downloader: efw-proto: emit responded signal at receiving response

Takashi Sakamoto o-takashi at sakamocchi.jp
Fri Aug 21 09:30:53 CEST 2020


HinawaFwResp has class virtual method for applications to handle received
frame on 1394 OHCI controller by overriding the method with own function
implementation.

This commit overrides the class virtual method and emits 'responded'
signal with the data of received response frame. The content of frame
is aligned to host-endianness, then passed to signal handlers.

Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
---
 efw-downloader/src/efw-proto.c | 43 ++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/efw-downloader/src/efw-proto.c b/efw-downloader/src/efw-proto.c
index 72959ac..bef81b3 100644
--- a/efw-downloader/src/efw-proto.c
+++ b/efw-downloader/src/efw-proto.c
@@ -3,6 +3,8 @@
 #include "efw-proto.h"
 #include "efw-proto-sigs-marshal.h"
 
+#include <sound/firewire.h>
+
 /**
  * SECTION:efw_proto
  * @Title: EfwProto
@@ -38,12 +40,16 @@ static void proto_finalize(GObject *obj)
     G_OBJECT_CLASS(efw_proto_parent_class)->finalize(obj);
 }
 
+static HinawaFwRcode proto_handle_response(HinawaFwResp *resp, HinawaFwTcode tcode);
+
 static void efw_proto_class_init(EfwProtoClass *klass)
 {
     GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
 
     gobject_class->finalize = proto_finalize;
 
+    HINAWA_FW_RESP_CLASS(klass)->requested = proto_handle_response;
+
     /**
      * EfwProto::responded:
      * @self: A #EfwProto.
@@ -126,3 +132,40 @@ void efw_proto_unbind(EfwProto *self)
 
     g_free(priv->buf);
 }
+
+static HinawaFwRcode proto_handle_response(HinawaFwResp *resp, HinawaFwTcode tcode)
+{
+    EfwProto *self = EFW_PROTO(resp);
+    EfwProtoPrivate *priv = efw_proto_get_instance_private(self);
+    const guint8 *req_frame = NULL;
+    gsize length = 0;
+    const struct snd_efw_transaction *frame;
+    guint status;
+    guint seqnum;
+    guint category;
+    guint command;
+    guint param_count;
+    int i;
+
+    hinawa_fw_resp_get_req_frame(resp, &req_frame, &length);
+    if (length < sizeof(*frame))
+        return HINAWA_FW_RCODE_DATA_ERROR;
+    frame = (const struct snd_efw_transaction *)req_frame;
+
+    status = GUINT32_FROM_BE(frame->status);
+    if (status > HINAWA_SND_EFW_STATUS_BAD_PARAMETER)
+        status = HINAWA_SND_EFW_STATUS_BAD;
+
+    seqnum = GUINT32_FROM_BE(frame->seqnum);
+    category = GUINT32_FROM_BE(frame->category);
+    command = GUINT32_FROM_BE(frame->command);
+    param_count = GUINT32_FROM_BE(frame->length) - sizeof(*frame) / sizeof(guint32);
+
+    for (i = 0; i < param_count; ++i)
+        priv->buf[i] = GUINT32_FROM_BE(frame->params[i]);
+
+    g_signal_emit(self, efw_proto_sigs[EFW_PROTO_SIG_TYPE_RESPONDED], 0,
+                  status, seqnum, category, command, priv->buf, param_count);
+
+    return HINAWA_FW_RCODE_COMPLETE;
+}
-- 
2.25.1



More information about the Alsa-devel mailing list