terom@154: #ifndef TRANSPORT_INTERNAL_H terom@154: #define TRANSPORT_INTERNAL_H terom@154: terom@154: /** terom@154: * @file terom@154: * terom@154: * The internal interface for transport implementations. terom@154: */ terom@154: #include "transport.h" terom@176: #include "object.h" terom@154: terom@155: #include terom@155: terom@154: /** terom@176: * The object_type for a transport_type terom@154: */ terom@176: extern const struct object_type transport_type_type; terom@154: terom@154: /** terom@154: * The definition of a transport type terom@154: */ terom@154: struct transport_type { terom@176: struct object_type base_type; terom@159: terom@176: /** terom@176: * Method table for implementation stuff. terom@176: * terom@176: * Note that it is the transport's resposibility to implement the behaviour described in transport.h terom@176: */ terom@176: struct transport_methods { terom@176: /** For transport_read() */ terom@176: err_t (*read) (transport_t *transport, void *buf, size_t *len, error_t *err); terom@176: terom@176: /** For transport_write() */ terom@176: err_t (*write) (transport_t *transport, const void *buf, size_t *len, error_t *err); terom@176: terom@176: /** terom@176: * The mask of event flags will be set to the given mask if this method is succesfull. terom@176: * terom@176: * The old mask is still available in transport::info::ev_mask. terom@176: */ terom@176: err_t (*events) (transport_t *transport, short mask, error_t *err); terom@176: terom@176: /** terom@176: * Release the transport's internal state, but not the transport itself. terom@176: * terom@176: * In other words, this should release everything inside the transport_t, but not free() the transport_t itself. terom@176: */ terom@176: void (*deinit) (transport_t *transport); terom@176: terom@176: /** terom@176: * Used by layered transports to handle transport_connected. terom@176: * terom@176: * If this is NULL, transport_connected will call the user callback directly, otherwise, it will proxy through this. terom@176: * terom@176: * The \a err param follows the same rules as for transport_connected() - NULL for success, error info otherwise. terom@176: * terom@176: * @param transport the transport state terom@176: * @param err error info if the connect failed terom@176: */ terom@176: void (*_connected) (transport_t *transport, const error_t *err); terom@176: } methods; terom@154: }; terom@154: terom@154: /** terom@154: * The base transport type terom@154: */ terom@154: struct transport { terom@176: struct object base_obj; terom@154: terom@154: /** User info */ terom@154: struct transport_info info; terom@156: terom@155: /** Are we connected? */ terom@155: bool connected; terom@154: }; terom@154: terom@154: /** terom@154: * Bind the given transport to the given type with the given user info. terom@154: * terom@157: * \a info may be given as NULL to not have any callbacks, but this will crash if any transport_* is called before terom@157: * transport_set_callbacks(). terom@157: * terom@154: * It is a bug to call this with a transport that is already bound. terom@154: */ terom@155: void transport_init (transport_t *transport, const struct transport_type *type, const struct transport_info *info); terom@154: terom@154: /** terom@154: * Check the type of the transport, and return the transport as a void* suitable for casting to the appropriate struct terom@159: * for the type, or any of its children. terom@154: * terom@154: * It is a bug to call this with a transport of a different type. terom@154: */ terom@154: void* transport_check (transport_t *transport, const struct transport_type *type); terom@154: terom@155: /** terom@155: * Mark the transport as connected, calling transport_methods::_connected if it exists and \a direct is not given, terom@155: * transport_callbacks::on_connected/transport_callbacks::on_error otherwise. terom@155: * terom@155: * If the connect succeeded, \a err should be given as NULL. If the connect failed, \a err should contain the error terom@155: * info. terom@155: * terom@155: * If called from the transport_methods::_connected method, pass in direct to avoid recursion. terom@155: * terom@183: * This sets the transport::connected flag before calling transport_callbacks::on_connected (i.e. directly) without any terom@183: * error set. terom@155: * terom@165: * XXX: implement proper layering of types by taking a transport_type arg and chaining down from there. terom@155: * terom@155: * @param transport the transport state terom@155: * @param err NULL for success, otherwise connect error code terom@155: * @param direct call the user callback directly, ignoring any method terom@155: */ terom@155: void transport_connected (transport_t *transport, const error_t *err, bool direct); terom@155: terom@155: /** terom@155: * Invoke the user callbacks based on the given TRANSPORT_* flags terom@155: */ terom@155: void transport_invoke (transport_t *transport, short what); terom@155: terom@155: /** terom@155: * Mark the transport as failed, calling transport_methods::on_error with the given error code. terom@155: */ terom@155: void transport_error (transport_t *transport, const error_t *err); terom@154: terom@154: #endif /* TRANSPORT_INTERNAL_H */