diff --git a/R/rzmq.R b/R/rzmq.R index 5ab7c58..ef4a87f 100644 --- a/R/rzmq.R +++ b/R/rzmq.R @@ -15,10 +15,6 @@ ## along with this program. If not, see . ## ########################################################################### -zmq.version <- function() { - .Call("get_zmq_version", PACKAGE="rzmq") -} - zmq.errno <- function() { .Call("get_zmq_errno", PACKAGE="rzmq") } @@ -27,10 +23,6 @@ zmq.strerror <- function() { .Call("get_zmq_strerror", PACKAGE="rzmq") } -init.context <- function() { - .Call("initContext", PACKAGE="rzmq") -} - init.socket <- function(context, socket.type) { .Call("initSocket", context, socket.type, PACKAGE="rzmq") } @@ -105,7 +97,7 @@ receive.double <- function(socket) { } poll.socket <- function(sockets, events, timeout=0L) { - if (timeout != -1L) timeout <- as.integer(timeout * 1e3) + if (timeout != -1L) timeout <- as.integer(timeout * 1000000) .Call("pollSocket", sockets, events, timeout) } @@ -200,3 +192,106 @@ set.send.timeout <- function(socket, option.value) { get.send.timeout <- function(socket) { .Call("get_sndtimeo", socket, PACKAGE="rzmq") } + +################################################################################# +# BDD functions +################################################################################# + +zmq.version <- function( x = NULL ){ + + version__ <- invisible( .Call("get_zmq_version", PACKAGE="rzmq") ) + + if( is.null( x ) ){ + return( version__ ) + }else if( toupper( x ) == 'MAJOR' ){ + return( as.integer( strsplit( split = '\\.', version__ )[[1]][1] ) ) + }else if( toupper( x ) == 'MINOR' ){ + return( as.integer( strsplit( split = '\\.', version__ )[[1]][2] ) ) + }else if( toupper( x ) == 'PATCH' ){ + return( as.integer( strsplit( split = '\\.', version__ )[[1]][3] ) ) + }else{ + stop( 'ERROR: x must be one of {NULL,"major","minor","patch"}.\n' ) + } +} + + +init.context <- function( io_threads = 1 ){ + io_threads <- as.integer( io_threads ) + if( io_threads < 1 ) + stop( 'ERROR: io_threads must be at least 1.\n' ) + invisible( .Call( "initContext", io_threads, PACKAGE = "rzmq" ) ) +} + +close.socket <- function( socket ){ + invisible( .Call( "closeSocket", socket, PACKAGE = "rzmq" ) ) +} + +get.keypair <- function(){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use get.keypair.\n' ) + keypair <- invisible( .Call( "get_keypair", PACKAGE = "rzmq" ) ) + names( keypair ) <- c( "public", "secret" ) + return( keypair ) +} + +set.curve.server <- function( socket ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use set.curve.server.\n' ) + invisible( .Call( "set_curve_server", socket, PACKAGE = "rzmq" ) ) +} + +get.curve.server <- function( socket ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use get.curve.server.\n' ) + curve_server <- invisible( .Call( "get_curve_server", socket, PACKAGE = "rzmq" ) ) + return( curve_server ) +} + + +set.public.key <- function( socket, option.value ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use set.public.key.\n' ) + invisible( .Call( "set_key", socket, "PUBLIC", as.character( option.value ), PACKAGE = "rzmq" ) ) +} + +get.public.key <- function( socket ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use get.public.key.\n' ) + public_key <- invisible( .Call( "get_key", socket, "PUBLIC", PACKAGE = "rzmq" ) ) + return( public_key ) +} + + +set.secret.key <- function( socket, option.value ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use set.secret.key.\n' ) + invisible( .Call( "set_key", socket, "SECRET", as.character( option.value ), PACKAGE = "rzmq" ) ) +} + +get.secret.key <- function( socket ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use get.secret.key.\n' ) + secret_key <- invisible( .Call( "get_key", socket, "SECRET", PACKAGE = "rzmq" ) ) + return( secret_key ) +} + + +set.server.key <- function( socket, option.value ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use set.server.key.\n' ) + invisible( .Call( "set_key", socket, "SERVER", as.character( option.value ), PACKAGE = "rzmq" ) ) +} + +get.server.key <- function( socket ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use get.server.key.\n' ) + server_key <- invisible( .Call( "get_key", socket, "SERVER", PACKAGE = "rzmq" ) ) + return( server_key ) +} + +get.io_threads <- function( context ){ + if( zmq.version( 'major' ) < 4 ) + stop( 'ERROR: ZeroMQ must be version 4 or newer to use get.io_threads.\n' ) + io_threads <- invisible( .Call( "get_io_threads", context, PACKAGE = "rzmq" ) ) + return( io_threads ) +} diff --git a/inst/zmq.hpp b/inst/zmq.hpp index 4f97f48..bac0bbf 100644 --- a/inst/zmq.hpp +++ b/inst/zmq.hpp @@ -396,6 +396,11 @@ namespace zmq { return ptr; } + + void* get_ptr(){ + return ptr; + } + private: void *ptr; diff --git a/man/close.socket.Rd b/man/close.socket.Rd new file mode 100644 index 0000000..bde4b97 --- /dev/null +++ b/man/close.socket.Rd @@ -0,0 +1,40 @@ +\name{close.socket} +\alias{close.socket} +\title{Close the connection to a socket.} +\description{Closes the connection to a socket.} +\usage{ +close.socket(socket) +} +\arguments{ + \item{socket}{a zmq socket object.} +} + +\value{TRUE if operation succeeds or FALSE if the operation fails} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/get.curve.server.Rd b/man/get.curve.server.Rd new file mode 100644 index 0000000..fa8a9e5 --- /dev/null +++ b/man/get.curve.server.Rd @@ -0,0 +1,40 @@ +\name{get.curve.server} +\alias{get.curve.server} +\title{Test whether a socket is a Curve server.} +\description{Test whether a socket is a Curve server.} +\usage{ +get.curve.server(socket) +} +\arguments{ + \item{socket}{a zmq socket object.} +} + +\value{1 if the socket is a Curve server; 0 otherwise.} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/get.io_threads.Rd b/man/get.io_threads.Rd new file mode 100644 index 0000000..e1bcfc2 --- /dev/null +++ b/man/get.io_threads.Rd @@ -0,0 +1,40 @@ +\name{get.io_threads} +\alias{get.io_threads} +\title{Get the number of io_threads used by a socket.} +\description{Get the number of io_threads used by a socket.} +\usage{ +get.io_threads(context) +} +\arguments{ + \item{context}{a zmq context object.} +} + +\value{An integer value representing the number of io_threads used by a socket.} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/get.keypair.Rd b/man/get.keypair.Rd new file mode 100644 index 0000000..5d11c5c --- /dev/null +++ b/man/get.keypair.Rd @@ -0,0 +1,38 @@ +\name{get.keypair} +\alias{get.keypair} +\title{Get a public and secret keypair for Curve authentication.} +\description{Get a public and secret keypair for Curve authentication.} +\usage{ +get.keypair() +} + +\value{A list of two strings, one representing the public key and one + representing the secret key.} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/get.public.key.Rd b/man/get.public.key.Rd new file mode 100644 index 0000000..76def10 --- /dev/null +++ b/man/get.public.key.Rd @@ -0,0 +1,40 @@ +\name{get.public.key} +\alias{get.public.key} +\title{Get the public key associated with a socket.} +\description{Get the public key associated with a socket.} +\usage{ +get.public.key(socket) +} +\arguments{ + \item{socket}{a zmq socket object.} +} + +\value{A string representing the public key of the socket.} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/get.secret.key.Rd b/man/get.secret.key.Rd new file mode 100644 index 0000000..b6ad764 --- /dev/null +++ b/man/get.secret.key.Rd @@ -0,0 +1,40 @@ +\name{get.secret.key} +\alias{get.secret.key} +\title{Get the secret key associated with a socket.} +\description{Get the secret key associated with a socket.} +\usage{ +get.secret.key(socket) +} +\arguments{ + \item{socket}{a zmq socket object.} +} + +\value{A string representing the secret key of the socket.} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/get.server.key.Rd b/man/get.server.key.Rd new file mode 100644 index 0000000..44a6304 --- /dev/null +++ b/man/get.server.key.Rd @@ -0,0 +1,40 @@ +\name{get.server.key} +\alias{get.server.key} +\title{Get the server key associated with a client socket.} +\description{Get the server key associated with a client socket.} +\usage{ +get.server.key(socket) +} +\arguments{ + \item{socket}{a zmq socket object.} +} + +\value{A string representing the server key of the socket.} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/init.context.Rd b/man/init.context.Rd index 7b8c01b..50b4ab5 100644 --- a/man/init.context.Rd +++ b/man/init.context.Rd @@ -8,11 +8,12 @@ initailize zmq context and zmq socket for to be used for further zmq operations. } \usage{ -init.context() +init.context(io_threads) init.socket(context, socket.type) } \arguments{ + \item{io_threads}{(optional) The number of io_threads to use. Defaults to 1.} \item{context}{returns a zmq context object.} \item{socket.type}{ The ZMQ socket type requested e.g. ZMQ_REQ,ZMQ_REP,ZMQ_PULL,ZMQ_PUSH, etc.} diff --git a/man/set.curve.server.Rd b/man/set.curve.server.Rd new file mode 100644 index 0000000..98e41ae --- /dev/null +++ b/man/set.curve.server.Rd @@ -0,0 +1,40 @@ +\name{set.curve.server} +\alias{set.curve.server} +\title{Set a socket to be a Curve server.} +\description{Set a socket to be a Curve server.} +\usage{ +set.curve.server(socket) +} +\arguments{ + \item{socket}{a zmq socket object.} +} + +\value{TRUE if operation succeeds or FALSE if the operation fails} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/set.public.key.Rd b/man/set.public.key.Rd new file mode 100644 index 0000000..aae810c --- /dev/null +++ b/man/set.public.key.Rd @@ -0,0 +1,42 @@ +\name{set.public.key} +\alias{set.public.key} +\title{Set the public key associated with a socket.} +\description{Set the public key associated with a socket.} +\usage{ +set.public.key(socket,option.value) +} +\arguments{ + \item{socket}{a zmq socket object.} + \item{option.value}{A string representing the public key to associate witht + the socket.} +} + +\value{TRUE if operation succeeds or FALSE if the operation fails} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/set.secret.key.Rd b/man/set.secret.key.Rd new file mode 100644 index 0000000..9b0bd0a --- /dev/null +++ b/man/set.secret.key.Rd @@ -0,0 +1,42 @@ +\name{set.secret.key} +\alias{set.secret.key} +\title{Get the secret key associated with a socket.} +\description{Get the secret key associated with a socket.} +\usage{ +set.secret.key(socket,option.value) +} +\arguments{ + \item{socket}{a zmq socket object.} + \item{option.value}{A string representing the secret key to associate witht + the socket.} +} + +\value{TRUE if operation succeeds or FALSE if the operation fails} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/set.server.key.Rd b/man/set.server.key.Rd new file mode 100644 index 0000000..8df6430 --- /dev/null +++ b/man/set.server.key.Rd @@ -0,0 +1,42 @@ +\name{set.server.key} +\alias{set.server.key} +\title{Get the server key associated with a client socket.} +\description{Get the server key associated with a client socket.} +\usage{ +set.server.key(socket,option.value) +} +\arguments{ + \item{socket}{a zmq socket object.} + \item{option.value}{A string representing the server key to associate witht + the socket.} +} + +\value{TRUE if operation succeeds or FALSE if the operation fails} + +\references{ +http://www.zeromq.org +http://api.zeromq.org +http://zguide.zeromq.org/page:all +} + +\author{ +ZMQ was written by Martin Sustrik and Martin Lucina . +rzmq was written by Whit Armstrong. +} + + +\seealso{ + \code{\link{connect.socket},\link{bind.socket},\link{receive.socket},\link{send.socket},\link{poll.socket}} +} +\examples{\dontrun{ + +library(rzmq) +context = init.context() +in.socket = init.socket(context,"ZMQ_PULL") +bind.socket(in.socket,"tcp://*:5557") + +out.socket = init.socket(context,"ZMQ_PUSH") +bind.socket(out.socket,"tcp://*:5558") +}} + +\keyword{utilities} diff --git a/man/zmq.version.Rd b/man/zmq.version.Rd index 17ec293..9e3960d 100644 --- a/man/zmq.version.Rd +++ b/man/zmq.version.Rd @@ -7,12 +7,24 @@ return the version string of the system zmq library } \usage{ -zmq.version() +zmq.version(x=NULL) } +\arguments{ + \item{x}{The desired level in the version hierarchy.} +} + \value{ - a string of the following format: major.minor.patch + If x == 'major' the return value is an integer representing the ZeroMQ + major version. + If x == 'minor' the return value is an integer representing the ZeroMQ + minor version. + If x == 'patch' the return value is an integer representing the ZeroMQ + patch. + If x is NULL the return value is a string of the following format: + major.minor.patch. This is the default. } + \references{ http://www.zeromq.org http://api.zeromq.org diff --git a/src/interface.cpp b/src/interface.cpp index 28be658..fd3b7c0 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -73,10 +73,6 @@ int string_to_socket_type(const std::string s) { return ZMQ_XPUB; } else if(s == "ZMQ_XSUB") { return ZMQ_XSUB; - } else if(s == "ZMQ_XREQ") { - return ZMQ_XREQ; - } else if(s == "ZMQ_XREP") { - return ZMQ_XREP; } else { return -1; } @@ -122,26 +118,6 @@ static void socketFinalizer(SEXP socket_) { } } -SEXP initContext() { - SEXP context_; - zmq::context_t* context; - try { - context = new zmq::context_t(1); - } catch(std::exception& e) { - REprintf("%s\n",e.what()); - return R_NilValue; - } - - if(context) { - PROTECT(context_ = R_MakeExternalPtr(reinterpret_cast(context),install("zmq::context_t*"),R_NilValue)); - R_RegisterCFinalizerEx(context_, contextFinalizer, TRUE); - UNPROTECT(1); - return context_; - } else { - return R_NilValue; - } -} - SEXP initSocket(SEXP context_, SEXP socket_type_) { SEXP socket_; @@ -974,3 +950,254 @@ SEXP rzmq_unserialize(SEXP data, SEXP rho) { UNPROTECT(2); return ans; } + +///////////////////////////////////////////////////////////////////////////////// +// BDD functions // +///////////////////////////////////////////////////////////////////////////////// + +//#include + +///// + +SEXP initContext( SEXP io_threads_ ){ + SEXP context_; + zmq::context_t* context; + + try { + context = new zmq::context_t( asReal( io_threads_ ) ); + + } catch(std::exception& e) { + REprintf("%s\n",e.what()); + return R_NilValue; + } + + if(context) { + PROTECT(context_ = R_MakeExternalPtr(reinterpret_cast(context),install("zmq::context_t*"),R_NilValue)); + R_RegisterCFinalizerEx(context_, contextFinalizer, TRUE); + UNPROTECT(1); + return context_; + } else { + return R_NilValue; + } +} + +///// + +SEXP closeSocket( SEXP socket_ ){ + + SEXP ans; + PROTECT( ans = allocVector( LGLSXP,1 ) ); + LOGICAL( ans )[0] = 1; + + try{ + zmq::socket_t* socket = reinterpret_cast( checkExternalPointer( socket_, "zmq::socket_t*" ) ); + socket->close(); + }catch( std::exception& e ){ + REprintf( "%s\n", e.what() ); + LOGICAL( ans )[0] = 0; + } + + UNPROTECT( 1 ); + return ans; +} + +///////////////// + + +#if ZMQ_VERSION_MAJOR >= 4 + +// keys are 40-byte strings plus one for null terminating character +#define KEY_SIZE 41 + + +SEXP get_keypair(){ + + SEXP vec; + PROTECT( vec = allocVector( VECSXP, 2 ) ); + + try{ + + char *public_key = (char*)malloc( KEY_SIZE ); + char *secret_key = (char*)malloc( KEY_SIZE ); + + // Create secret and public keys + // Signature: int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key) + zmq_curve_keypair( public_key, secret_key ); + + // Populate vector with public and secret keys + SET_VECTOR_ELT( vec, 0, mkString( public_key ) ); + SET_VECTOR_ELT( vec, 1, mkString( secret_key ) ); + + }catch( std::exception& e ){ + REprintf("%s\n",e.what()); + } + + UNPROTECT( 1 ); + return vec; +} + +////////////// + +SEXP set_curve_server( SEXP socket_ ){ + + SEXP ans; + PROTECT( ans = allocVector( INTSXP, 1 ) ); + INTEGER( ans )[0] = 0; + + try{ + + // Cast function parameters from SEXP to required C data type + zmq::socket_t* socket = reinterpret_cast( checkExternalPointer( socket_, "zmq::socket_t*" ) ); + + if( !socket ){ + REprintf( "bad socket object.\n" ); + return R_NilValue; + } + + // Set ZMQ_CURVE_SERVER option for socket to 1 (only called wfor server socket) + int option_value = 1; + socket->setsockopt( ZMQ_CURVE_SERVER, &option_value, sizeof( int ) ); + + }catch( std::exception& e ){ + REprintf( "%s\n", e.what() ); + LOGICAL( ans )[0] = -1; + } + + UNPROTECT(1); + return ans; +} + +//////////////////////////////// + +SEXP get_curve_server( SEXP socket_ ){ + + SEXP ans; + PROTECT( ans = allocVector( INTSXP, 1 ) ); + + try{ + // Cast function parameters from SEXP to required C data type + zmq::socket_t* socket = reinterpret_cast( checkExternalPointer( socket_, "zmq::socket_t*" ) ); + + int option_value = -1; + size_t option_len = sizeof( int ); + + socket->getsockopt( ZMQ_CURVE_SERVER, &option_value, &option_len ); + + // Populate ans with value of ZMQ_CURVE_SERVER + INTEGER( ans )[0] = option_value; + + }catch( std::exception& e ){ + REprintf( "%s\n", e.what() ); + } + + UNPROTECT(1); + return ans; +} + + +////////////////////////// + +SEXP set_key( SEXP socket_, SEXP key_type_, SEXP option_value_ ){ + + SEXP ans; + PROTECT( ans = allocVector( LGLSXP, 1 ) ); + LOGICAL( ans )[0] = 0; + + try{ + // Cast function parameters from SEXP to required C data type + zmq::socket_t* socket = reinterpret_cast( checkExternalPointer( socket_, "zmq::socket_t*" ) ); + + if(!socket) { REprintf("bad socket object.\n");return R_NilValue; } + + // Cast option_value_ to const char* pointer + const char* option_value = CHAR( STRING_ELT( option_value_, 0 ) ); + const char* key_type_char = CHAR( STRING_ELT( key_type_, 0 ) ); + + if( std::strcmp( key_type_char, "PUBLIC" ) == 0){ + socket->setsockopt( ZMQ_CURVE_PUBLICKEY, option_value, KEY_SIZE ); + + }else if( std::strcmp( key_type_char, "SECRET" ) == 0 ){ + socket->setsockopt( ZMQ_CURVE_SECRETKEY, option_value, KEY_SIZE ); + + }else if( std::strcmp( key_type_char, "SERVER" ) == 0 ){ + socket->setsockopt( ZMQ_CURVE_SERVERKEY, option_value, KEY_SIZE ); + + } + + }catch( std::exception& e ){ + REprintf( "%s\n", e.what() ); + LOGICAL( ans )[0] = 1; } + + UNPROTECT(1); + return ans; +} + +//////////////////////////////// + +SEXP get_key( SEXP socket_, SEXP key_type_ ){ + + SEXP ans; + PROTECT( ans = allocVector( STRSXP, 1 ) ); + + try{ + // Cast function parameters from SEXP to required C data type + zmq::socket_t* socket = reinterpret_cast( checkExternalPointer( socket_, "zmq::socket_t*" ) ); + + if(!socket) { REprintf("bad socket object.\n");return R_NilValue; } + + char* option_value = (char*)malloc( KEY_SIZE ); + size_t option_len = KEY_SIZE; + + + const char* key_type_char = CHAR( STRING_ELT( key_type_, 0 ) ); + + if( std::strcmp( key_type_char, "PUBLIC" ) == 0 ){ + socket->getsockopt( ZMQ_CURVE_PUBLICKEY, option_value, &option_len ); + + }else if( std::strcmp( key_type_char, "SECRET" ) == 0 ){ + socket->getsockopt( ZMQ_CURVE_SECRETKEY, option_value, &option_len ); + + }else if( std::strcmp( key_type_char, "SERVER" ) == 0 ){ + socket->getsockopt( ZMQ_CURVE_SERVERKEY, option_value, &option_len ); + + } + + // Populate ans with value of option_value + SET_STRING_ELT( ans, 0, mkChar( option_value ) ); + + }catch( std::exception& e ){ + REprintf( "%s\n", e.what() ); + } + + UNPROTECT(1); + return ans; +} + +//////////////// + +SEXP get_io_threads( SEXP context_ ){ + + SEXP io_threads_; + PROTECT( io_threads_ = allocVector( INTSXP, 1 ) ); + + try{ + + zmq::context_t* context = reinterpret_cast( R_ExternalPtrAddr( context_ ) ); + void* context_ptr = context->get_ptr(); + int io_threads = zmq_ctx_get( context_ptr, ZMQ_IO_THREADS ); + + // Populate vector with number of io_threads + INTEGER( io_threads_ )[0] = io_threads; + + }catch( std::exception& e ){ + REprintf("%s\n",e.what()); + } + + UNPROTECT( 1 ); + + return io_threads_; +} + +#endif + +// END OF FILE diff --git a/src/interface.h b/src/interface.h index 0431b00..0c366a1 100644 --- a/src/interface.h +++ b/src/interface.h @@ -31,7 +31,6 @@ extern "C" { SEXP get_zmq_version(); SEXP get_zmq_errno(); SEXP get_zmq_strerror(); - SEXP initContext(); SEXP initSocket(SEXP context_, SEXP socket_type_); SEXP bindSocket(SEXP socket_, SEXP address_); SEXP connectSocket(SEXP socket_, SEXP address_); @@ -64,6 +63,24 @@ extern "C" { SEXP pollSocket(SEXP socket_, SEXP events_, SEXP timeout_); SEXP get_sndtimeo(SEXP socket_); SEXP set_sndtimeo(SEXP socket_, SEXP option_value_); + + /////////////////////////////////////////////////////////////////////////////// + // BDD functions // + /////////////////////////////////////////////////////////////////////////////// + + SEXP closeSocket( SEXP socket_ ); + + SEXP get_keypair(); + + SEXP set_curve_server( SEXP socket_ ); + SEXP get_curve_server( SEXP socket_ ); + + SEXP set_key( SEXP socket_, SEXP key_type_, SEXP option_value_ ); + SEXP get_key( SEXP socket_, SEXP key_type_ ); + + SEXP initContext( SEXP io_threads_ ); + + SEXP get_io_threads( SEXP context_ ); } #endif // INTERFACE_HPP