transport: Switch transports as required on GET_MBOX_INFO
Also flush the event state out via the new transport. This must be done
after the command has completed for the mbox transport.
Change-Id: I251fb949ae67a477288d0d57a1a6afe5b2af5f8f
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/test/mbox.c b/test/mbox.c
index 6549813..f7560f1 100644
--- a/test/mbox.c
+++ b/test/mbox.c
@@ -70,6 +70,8 @@
fstat(fd, &details);
map = mmap(NULL, details.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ printf("%s:%d: details.st_size: %ld, RESPONSE_OFFSET + len: %ld\n",
+ __func__, __LINE__, details.st_size, RESPONSE_OFFSET + len);
assert(map != MAP_FAILED);
assert(details.st_size >= (RESPONSE_OFFSET + len));
diff --git a/transport_dbus.c b/transport_dbus.c
index 0444284..1d3f0cd 100644
--- a/transport_dbus.c
+++ b/transport_dbus.c
@@ -9,6 +9,18 @@
#include "dbus.h"
#include "mboxd.h"
#include "protocol.h"
+#include "transport.h"
+
+int transport_dbus_flush_events(struct mbox_context *context)
+{
+ /* FIXME ! */
+ MSG_ERR("%s is unimplemented!\n", __func__);
+ return 0;
+}
+
+static const struct transport_ops transport_dbus_ops = {
+ .flush_events = transport_dbus_flush_events,
+};
static int transport_dbus_get_info(sd_bus_message *m, void *userdata,
sd_bus_error *ret_error)
@@ -34,6 +46,10 @@
return rc;
}
+ /* Switch transport to DBus. This is fine as DBus signals are async */
+ context->transport = &transport_dbus_ops;
+ context->transport->flush_events(context);
+
rc = sd_bus_message_new_method_return(m, &n);
if (rc < 0) {
MSG_ERR("sd_bus_message_new_method_return failed: %d\n", rc);
diff --git a/transport_mbox.c b/transport_mbox.c
index d325b19..24d4734 100644
--- a/transport_mbox.c
+++ b/transport_mbox.c
@@ -121,6 +121,10 @@
return 0;
}
+static const struct transport_ops transport_mbox_ops = {
+ .flush_events = transport_mbox_flush_events,
+};
+
/* Command Handlers */
/*
@@ -170,6 +174,12 @@
return rc;
}
+ /*
+ * Switch transport to mbox, however we need to delay flushing the
+ * event state until after the command is processed.
+ */
+ context->transport = &transport_mbox_ops;
+
resp->args[0] = io.resp.api_version;
if (io.resp.api_version == API_VERSION_1) {
put_u16(&resp->args[1], io.resp.v1.read_window_size);
@@ -477,6 +487,14 @@
}
}
+ if (context->transport != &transport_mbox_ops) {
+ if (cmd != MBOX_C_RESET_STATE && cmd != MBOX_C_GET_MBOX_INFO) {
+ MSG_ERR("Cannot switch transport with command %d\n",
+ cmd);
+ return -EPROTO;
+ }
+ }
+
if (!(context->state & MAPS_MEM)) {
if (cmd != MBOX_C_RESET_STATE && cmd != MBOX_C_GET_MBOX_INFO
&& cmd != MBOX_C_ACK) {
@@ -513,6 +531,7 @@
*/
static int handle_mbox_req(struct mbox_context *context, union mbox_regs *req)
{
+ const struct transport_ops *old_transport = context->transport;
struct mbox_msg resp = {
.command = req->msg.command,
.seq = req->msg.seq,
@@ -522,6 +541,7 @@
int rc = 0, len, i;
MSG_INFO("Received MBOX command: %u\n", req->msg.command);
+
rc = check_req_valid(context, req);
if (!rc) {
mboxd_mbox_handler handler;
@@ -552,6 +572,11 @@
rc = -errno;
}
+ if (context->transport != old_transport &&
+ context->transport == &transport_mbox_ops) {
+ transport_mbox_flush_events(context);
+ }
+
return rc;
}
@@ -606,10 +631,6 @@
return handle_mbox_req(context, &req);
}
-static const struct transport_ops transport_mbox_ops = {
- .flush_events = transport_mbox_flush_events,
-};
-
int __transport_mbox_init(struct mbox_context *context, const char *path)
{
int fd;