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