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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxx>
---
 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




[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux