vpnor: Hijack protocol rather than transport

By hijacking the transport the changes in behaviour were limited to the
mailbox interface. Now that we have a DBus interface as well this would
lead to inconsistent behaviour dependent on the transport.

Instead of hooking the transport, push the hook down to the protocol
level where we will achieve consistent behaviour across all transports.

Change-Id: I437866a6dbda107149336c15a00ee1aa058f5875
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
diff --git a/protocol_negotiate_version.c b/protocol_negotiate_version.c
new file mode 100644
index 0000000..849363f
--- /dev/null
+++ b/protocol_negotiate_version.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (C) 2018 IBM Corp.
+#include "config.h"
+
+#include <errno.h>
+
+#include "mbox.h"
+#include "protocol.h"
+
+static const struct protocol_ops protocol_ops_v1 = {
+	.reset = protocol_v1_reset,
+	.get_info = protocol_v1_get_info,
+	.get_flash_info = protocol_v1_get_flash_info,
+	.create_window = protocol_v1_create_window,
+	.mark_dirty = protocol_v1_mark_dirty,
+	.erase = NULL,
+	.flush = protocol_v1_flush,
+	.close = protocol_v1_close,
+	.ack = protocol_v1_ack,
+};
+
+static const struct protocol_ops protocol_ops_v2 = {
+	.reset = protocol_v1_reset,
+	.get_info = protocol_v2_get_info,
+	.get_flash_info = protocol_v2_get_flash_info,
+	.create_window = protocol_v2_create_window,
+	.mark_dirty = protocol_v2_mark_dirty,
+	.erase = protocol_v2_erase,
+	.flush = protocol_v2_flush,
+	.close = protocol_v2_close,
+	.ack = protocol_v1_ack,
+};
+
+static const struct protocol_ops *protocol_ops_map[] = {
+	[0] = NULL,
+	[1] = &protocol_ops_v1,
+	[2] = &protocol_ops_v2,
+};
+
+int protocol_negotiate_version(struct mbox_context *context,
+				   uint8_t requested)
+{
+	/* Check we support the version requested */
+	if (requested < API_MIN_VERSION)
+		return -EINVAL;
+
+	context->version = (requested > API_MAX_VERSION) ?
+				API_MAX_VERSION : requested;
+
+	context->protocol = protocol_ops_map[context->version];
+
+	return context->version;
+}