| /* | 
 |     Copyright (c) 2012-2013 250bpm s.r.o. | 
 |  | 
 |     Permission is hereby granted, free of charge, to any person obtaining a copy | 
 |     of this software and associated documentation files (the "Software"), | 
 |     to deal in the Software without restriction, including without limitation | 
 |     the rights to use, copy, modify, merge, publish, distribute, sublicense, | 
 |     and/or sell copies of the Software, and to permit persons to whom | 
 |     the Software is furnished to do so, subject to the following conditions: | 
 |  | 
 |     The above copyright notice and this permission notice shall be included | 
 |     in all copies or substantial portions of the Software. | 
 |  | 
 |     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
 |     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
 |     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | 
 |     THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
 |     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | 
 |     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | 
 |     IN THE SOFTWARE. | 
 | */ | 
 |  | 
 | #ifndef NN_TRANSPORT_INCLUDED | 
 | #define NN_TRANSPORT_INCLUDED | 
 |  | 
 | #include "nn.h" | 
 |  | 
 | #include "utils/list.h" | 
 | #include "utils/aio.h" | 
 | #include "utils/msg.h" | 
 |  | 
 | #include <stddef.h> | 
 | #include <stdint.h> | 
 |  | 
 | /*  This is the API between the nanomsg core and individual transports. */ | 
 |  | 
 | struct nn_sock; | 
 | struct nn_cp; | 
 |  | 
 | /******************************************************************************/ | 
 | /*  The base class for endpoints.                                             */ | 
 | /******************************************************************************/ | 
 |  | 
 | struct nn_epbase; | 
 |  | 
 | struct nn_epbase_vfptr { | 
 |  | 
 |     /*  Ask the endpoint to terminate itself. The endpoint is allowed to linger | 
 |         to send the pending outbound data. Once it's ready, it will close itself | 
 |         using nn_epbase_term() which, in turn, will unregister the endpoint from | 
 |         the socket. */ | 
 |     void (*close) (struct nn_epbase *self); | 
 | }; | 
 |  | 
 | /*  The member of this structure are used internally by the core. Never use | 
 |     or modify them directly from the transport. */ | 
 | struct nn_epbase { | 
 |     const struct nn_epbase_vfptr *vfptr; | 
 |     struct nn_sock *sock; | 
 |     int eid; | 
 |     struct nn_list_item item; | 
 |     char addr [NN_SOCKADDR_MAX + 1]; | 
 | }; | 
 |  | 
 | /*  Creates a new endpoint. Returns the endpoint ID. */ | 
 | void nn_epbase_init (struct nn_epbase *self, | 
 |     const struct nn_epbase_vfptr *vfptr, const char *addr, void *hint); | 
 |  | 
 | /*  Destroys the endpoint. */ | 
 | void nn_epbase_term (struct nn_epbase *self); | 
 |  | 
 | /*  Returns the default completion port associated with the current socket. */ | 
 | struct nn_cp *nn_epbase_getcp (struct nn_epbase *self); | 
 |  | 
 | /*  Returns the address associated with this endpoint. */ | 
 | const char *nn_epbase_getaddr (struct nn_epbase *self); | 
 |  | 
 | /*  Retrieve value of a socket option. */ | 
 | void nn_epbase_getopt (struct nn_epbase *self, int level, int option, | 
 |     void *optval, size_t *optvallen); | 
 |  | 
 | /******************************************************************************/ | 
 | /*  The base class for pipes.                                                 */ | 
 | /******************************************************************************/ | 
 |  | 
 | struct nn_pipebase; | 
 |  | 
 | /*  This value is returned by pipe's send and recv functions to signalise that | 
 |     more sends/recvs are not possible at the moment. From that moment on, | 
 |     the core will stop invoking the function. To re-establish the message | 
 |     flow nn_pipebase_received (respectively nn_pipebase_sent) should | 
 |     be called. */ | 
 | #define NN_PIPEBASE_RELEASE 1 | 
 |  | 
 | /*  Internal pipe states. */ | 
 | #define NN_PIPEBASE_INSTATE_DEACTIVATED 0 | 
 | #define NN_PIPEBASE_INSTATE_IDLE 1 | 
 | #define NN_PIPEBASE_INSTATE_RECEIVING 2 | 
 | #define NN_PIPEBASE_INSTATE_RECEIVED 3 | 
 | #define NN_PIPEBASE_INSTATE_ASYNC 4 | 
 | #define NN_PIPEBASE_OUTSTATE_DEACTIVATED 0 | 
 | #define NN_PIPEBASE_OUTSTATE_IDLE 1 | 
 | #define NN_PIPEBASE_OUTSTATE_SENDING 2 | 
 | #define NN_PIPEBASE_OUTSTATE_SENT 3 | 
 | #define NN_PIPEBASE_OUTSTATE_ASYNC 4 | 
 |  | 
 | struct nn_pipebase_vfptr { | 
 |     int (*send) (struct nn_pipebase *self, struct nn_msg *msg); | 
 |     int (*recv) (struct nn_pipebase *self, struct nn_msg *msg); | 
 | }; | 
 |  | 
 | /*  The member of this structure are used internally by the core. Never use | 
 |     or modify them directly from the transport. */ | 
 | struct nn_pipebase { | 
 |     const struct nn_pipebase_vfptr *vfptr; | 
 |     uint8_t instate; | 
 |     uint8_t outstate; | 
 |     struct nn_epbase *epbase; | 
 |     void *data; | 
 | }; | 
 |  | 
 | /*  Initialise the pipe.  */ | 
 | int nn_pipebase_init (struct nn_pipebase *self, | 
 |     const struct nn_pipebase_vfptr *vfptr, struct nn_epbase *epbase); | 
 |  | 
 | /*  Terminate the pipe. */ | 
 | void nn_pipebase_term (struct nn_pipebase *self); | 
 |  | 
 | /*  Informs the user that the pipe is ready for sending and that asynchronous | 
 |     receiving of messages have already started. */ | 
 | void nn_pipebase_activate (struct nn_pipebase *self); | 
 |  | 
 | /*  Call this function when new message was fully received. */ | 
 | void nn_pipebase_received (struct nn_pipebase *self); | 
 |  | 
 | /*  Call this function when current outgoing message was fully sent. */ | 
 | void nn_pipebase_sent (struct nn_pipebase *self); | 
 |  | 
 | /*  Returns the default completion port associated with the pipe. */ | 
 | struct nn_cp *nn_pipebase_getcp (struct nn_pipebase *self); | 
 |  | 
 |  | 
 | /******************************************************************************/ | 
 | /*  The transport class.                                                      */ | 
 | /******************************************************************************/ | 
 |  | 
 | struct nn_transport { | 
 |  | 
 |     /*  Following methods are guarded by a global critical section. Two of these | 
 |         function will never be invoked in parallel. */ | 
 |     const char *(*name) (void); | 
 |     void (*init) (void); | 
 |     void (*term) (void); | 
 |  | 
 |     /*  Following methods are guarded by a socket-wide critical section. | 
 |         Two of these function will never be invoked in parallel on the same | 
 |         socket. */ | 
 |     int (*bind) (const char *addr, void *hint, struct nn_epbase **epbase); | 
 |     int (*connect) (const char *addr, void *hint, struct nn_epbase **epbase); | 
 |  | 
 |     /*  This member is owned by the core. Never touch it directly from | 
 |         the transport. */ | 
 |     struct nn_list_item list; | 
 | }; | 
 |  | 
 | #endif |