diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs
index 08944196f..63f225100 100644
--- a/ipc/codegen/src/codegen.rs
+++ b/ipc/codegen/src/codegen.rs
@@ -13,7 +13,6 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
-
use aster;
use syntax::ast::{
@@ -61,10 +60,24 @@ pub fn expand_ipc_implementation(
};
push_client(cx, &builder, &item, &dispatches, push);
+ push_handshake_struct(cx, push);
push(Annotatable::Item(impl_item))
}
+fn push_handshake_struct(cx: &ExtCtxt, push: &mut FnMut(Annotatable)) {
+ let handshake_item = quote_item!(cx,
+ #[derive(Serialize, Deserialize)]
+ pub struct BinHandshake {
+ api_version: String,
+ protocol_version: String,
+ _reserved: Vec,
+ }
+ ).unwrap();
+
+ push(Annotatable::Item(handshake_item));
+}
+
fn field_name(builder: &aster::AstBuilder, arg: &Arg) -> ast::Ident {
match arg.pat.node {
PatKind::Ident(_, ref ident, _) => builder.id(ident.node),
@@ -548,6 +561,14 @@ fn implement_interface(
let dispatch_arms = implement_dispatch_arms(cx, builder, &dispatch_table, false);
let dispatch_arms_buffered = implement_dispatch_arms(cx, builder, &dispatch_table, true);
+ let handshake_arm = quote_arm!(&cx, 0 => {
+ let handshake_payload = ::bincode::serde::deserialize_from::<_, BinHandshake>(r, ::bincode::SizeLimit::Infinite).unwrap();
+ ::bincode::serde::serialize::(&Self::handshake(&::ipc::Handshake {
+ api_version: ::semver::Version::parse(&handshake_payload.api_version).unwrap(),
+ protocol_version: ::semver::Version::parse(&handshake_payload.protocol_version).unwrap(),
+ }), ::bincode::SizeLimit::Infinite).unwrap()
+ });
+
Ok((quote_item!(cx,
impl $impl_generics ::ipc::IpcInterface<$ty> for $ty $where_clause {
fn dispatch(&self, r: &mut R) -> Vec
@@ -561,6 +582,9 @@ fn implement_interface(
}
// method_num is a 16-bit little-endian unsigned number
match method_num[1] as u16 + (method_num[0] as u16)*256 {
+ // handshake
+ $handshake_arm
+ // user methods
$dispatch_arms
_ => vec![]
}
diff --git a/ipc/rpc/src/interface.rs b/ipc/rpc/src/interface.rs
index 060da36a9..5b5a30b27 100644
--- a/ipc/rpc/src/interface.rs
+++ b/ipc/rpc/src/interface.rs
@@ -22,9 +22,8 @@ use std::sync::atomic::*;
use semver::Version;
pub struct Handshake {
- protocol_version: Version,
- api_version: Version,
- reserved: [u8; 64],
+ pub protocol_version: Version,
+ pub api_version: Version,
}
pub trait IpcConfig {
@@ -34,13 +33,22 @@ pub trait IpcConfig {
fn protocol_version() -> Version {
Version::parse("1.0.0").unwrap()
}
+ fn handshake(handshake: &Handshake) -> bool {
+ handshake.protocol_version == Self::protocol_version() &&
+ handshake.api_version == Self::api_version()
+ }
+}
+
+pub enum Error {
+ UnkownSystemCall,
+ ClientUnsupported,
}
pub trait IpcInterface where T: IpcConfig {
/// reads the message from io, dispatches the call and returns serialized result
fn dispatch(&self, r: &mut R) -> Vec where R: Read;
- /// deserialize the payload from buffer, dispatches invoke and returns serialized result
+ /// deserializes the payload from buffer, dispatches invoke and returns serialized result
/// (for non-blocking io)
fn dispatch_buf(&self, method_num: u16, buf: &[u8]) -> Vec;
}
diff --git a/ipc/rpc/src/lib.rs b/ipc/rpc/src/lib.rs
index a0d718871..f0083e66e 100644
--- a/ipc/rpc/src/lib.rs
+++ b/ipc/rpc/src/lib.rs
@@ -20,4 +20,4 @@ extern crate ethcore_devtools as devtools;
extern crate semver;
pub mod interface;
-pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig};
+pub use interface::{IpcInterface, IpcSocket, invoke, IpcConfig, Handshake, Error};
diff --git a/ipc/tests/service.rs.in b/ipc/tests/service.rs.in
index 14de716da..f48596e6c 100644
--- a/ipc/tests/service.rs.in
+++ b/ipc/tests/service.rs.in
@@ -16,6 +16,7 @@
use std::sync::RwLock;
use std::ops::*;
+use ipc::IpcConfig;
pub struct Service {
pub commits: RwLock,