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