To be backward compatible, the old obex_event_t callback type is still supported but the documentation only refers to the new type and its functions. --- doc/openobex.coverpage | 20 +----- include/openobex/obex.h | 44 +++++++++++++-- lib/obex.c | 143 +++++++++++++++++++++++++++------------------- lib/obex.sym | 3 + lib/obex_main.c | 70 ++++++++++++++++++++++- lib/obex_main.h | 5 +- 6 files changed, 201 insertions(+), 84 deletions(-)
diff --git a/doc/openobex.coverpage b/doc/openobex.coverpage index 1f75eb4..1f7715b 100644 --- a/doc/openobex.coverpage +++ b/doc/openobex.coverpage @@ -31,9 +31,9 @@ You might also find the OpenOBEX test applications useful. To be able to use the OpenOBEX API you must include the files openobex/obex_const.h and openobex/obex.h. -First of all you must create an OBEX instance by calling #OBEX_Init. +First of all you must create an OBEX instance by calling #OBEX_New. In this call you specify what transport you want to use, an event callback, and optional flags. -#OBEX_Init will return a handle which shall be passed to almost all other functions. +#OBEX_New will return a handle which shall be passed to almost all other functions. To let the parser do some work you must call #OBEX_HandleInput. It will block for at-most the specified timeout for read and write actions. @@ -41,19 +41,7 @@ You can call #OBEX_GetFD if you want to do select() yourself (this may not work \subsection callback_sec The event callback -The event callback shall be a function with the #obex_event_t prototype: - \code -void *obex_event_t(obex_t *handle, obex_object_t *obj, int mode, int event, int obex_cmd, int obex_rsp) - \endcode - -Arguments: - - handle : OBEX handle - - obj : OBEX object - - mode : OBEX_MODE_CLIENT for client event or OBEX_MODE_SERVER, for server event - - event : The event. See obex_const.h for possible events (OBEX_EV_*) - - obex_cmd : Command if any (depending on event type). See obex_const.h for commands (OBEX_CMD_*) - - obex_rsp : Response if any (depending on event type). See obex_const.h for responses (OBEX_RSP_*) - +The event callback shall be a function with the #obex_event_cb_t prototype. To this function events from the library will be passed to you, for example when an operation finishes. #OBEX_SetUserData and #OBEX_GetUserData are useful if you need to access your own private data from inside the event callback. @@ -125,7 +113,7 @@ generic function #OBEX_ServerRegister or one of the specialized: - #BtOBEX_ServerRegister. When an incoming connection is coming you'll get an #OBEX_EV_ACCEPTHINT event. -If you ignore this event no more incoming connections will be accepted but if you call #OBEX_ServerAccept, +If you ignore this event no more incoming connections will be accepted but if you call #OBEX_Accept, you'll get back a new OBEX handle and the old handle will still be listening to connections. When an incoming request comes, you will first get an #OBEX_EV_REQHINT event. The supplied diff --git a/include/openobex/obex.h b/include/openobex/obex.h index 6bf91d4..315601d 100644 --- a/include/openobex/obex.h +++ b/include/openobex/obex.h @@ -60,18 +60,52 @@ struct obex_object; typedef struct obex obex_t; typedef struct obex_object obex_object_t; -typedef void (*obex_event_t)(obex_t *handle, obex_object_t *obj, int mode, int event, int obex_cmd, int obex_rsp); - #include <openobex/obex_const.h> /* + * OBEX API (deprecated) + */ +/** The user event callback. + * \deprecated Use #obex_event_cb_t and its functions instead. + * \param handle the obex handle + * \param obj the object that this callback is about + * \param mode one of the OBEX_MODE_* + * \param event one of the OBEX_EVE_* + * \param obex_cmd the current OBEX command code + * \param obex_rsp the current OBEX response code (client only) + */ +typedef void (*obex_event_t)(obex_t *handle, obex_object_t *obj, int mode, + int event, int obex_cmd, int obex_rsp); + +OPENOBEX_SYMBOL(obex_t *) OBEX_Init(int transport, obex_event_t eventcb, + unsigned int flags); +OPENOBEX_SYMBOL(void) OBEX_SetUserCallBack(obex_t *self, + obex_event_t eventcb, + void * data); +OPENOBEX_SYMBOL(obex_t *) OBEX_ServerAccept(obex_t *server, + obex_event_t eventcb, void * data); + +/* * OBEX API */ -OPENOBEX_SYMBOL(obex_t *) OBEX_Init(int transport, obex_event_t eventcb, unsigned int flags); +/** The user event callback. + * \param handle the obex handle + * \param obj the object that this callback is about + * \param mode the current #obex_mode + * \param event the current #obex_event + * \param obex_cmd the current OBEX command code + * \param obex_rsp the current OBEX response code (client only) + */ +typedef void (*obex_event_cb_t)(obex_t *handle, obex_object_t *obj, + enum obex_mode mode, enum obex_event event, + uint8_t cmd, uint8_t rsp); + +OPENOBEX_SYMBOL(obex_t *) OBEX_New(enum obex_transport_type transport, + obex_event_cb_t eventcb, unsigned int flags); OPENOBEX_SYMBOL(void) OBEX_Cleanup(obex_t *self); OPENOBEX_SYMBOL(void) OBEX_SetUserData(obex_t *self, void * data); OPENOBEX_SYMBOL(void *) OBEX_GetUserData(obex_t *self); -OPENOBEX_SYMBOL(void) OBEX_SetUserCallBack(obex_t *self, obex_event_t eventcb, void * data); +OPENOBEX_SYMBOL(void) OBEX_SetEventCb(obex_t *self, obex_event_cb_t eventcb, void * data); OPENOBEX_SYMBOL(int) OBEX_SetTransportMTU(obex_t *self, uint16_t mtu_rx, uint16_t mtu_tx_max); OPENOBEX_SYMBOL(int) OBEX_GetFD(obex_t *self); @@ -85,7 +119,7 @@ OPENOBEX_SYMBOL(int) OBEX_CustomDataFeed(obex_t *self, uint8_t *inputbuf, int ac OPENOBEX_SYMBOL(int) OBEX_HandleInput(obex_t *self, int timeout); OPENOBEX_SYMBOL(int) OBEX_ServerRegister(obex_t *self, struct sockaddr *saddr, int addrlen); -OPENOBEX_SYMBOL(obex_t *) OBEX_ServerAccept(obex_t *server, obex_event_t eventcb, void * data); +OPENOBEX_SYMBOL(obex_t *) OBEX_Accept(obex_t *server); OPENOBEX_SYMBOL(int) OBEX_Request(obex_t *self, obex_object_t *object); OPENOBEX_SYMBOL(int) OBEX_CancelRequest(obex_t *self, int nice); diff --git a/lib/obex.c b/lib/obex.c index 229d09d..0522bef 100644 --- a/lib/obex.c +++ b/lib/obex.c @@ -67,6 +67,7 @@ /** Initialize OBEX. + \deprecated Use OBEX_New() instead of this function. \param transport Which transport to use. The following transports are available : - #OBEX_TRANS_IRDA : Use regular IrDA socket (need an IrDA stack) - #OBEX_TRANS_INET : Use regular TCP/IP socket @@ -90,65 +91,41 @@ obex_t * CALLAPI OBEX_Init(int transport, obex_event_t eventcb, unsigned int flags) { obex_t *self; - char *env; - -#if OBEX_DEBUG - obex_debug = OBEX_DEBUG; -#else - obex_debug = -1; -#endif -#if OBEX_DUMP - obex_dump = OBEX_DUMP; -#else - obex_dump = 0; -#endif - - env = getenv("OBEX_DEBUG"); - if (env) - obex_debug = atoi(env); - - env = getenv("OBEX_DUMP"); - if (env) - obex_dump = atoi(env); obex_return_val_if_fail(eventcb != NULL, NULL); - self = calloc(1, sizeof(*self)); - if (self == NULL) - return NULL; - - self->eventcb = eventcb; - self->init_flags = flags; - self->mode = OBEX_MODE_SERVER; - self->state = STATE_IDLE; - self->rsp_mode = OBEX_RSP_MODE_NORMAL; + self = obex_new((enum obex_transport_type)transport, flags); + if (self) + self->old_eventcb = eventcb; - /* Safe values. - * Both self->mtu_rx and self->mtu_tx_max can be increased by app - * self->mtu_tx will be whatever the other end sends us - Jean II */ - self->mtu_rx = OBEX_DEFAULT_MTU; - self->mtu_tx = OBEX_MINIMUM_MTU; - self->mtu_tx_max = OBEX_DEFAULT_MTU; + return self; +} - if (obex_transport_init(self, transport) < 0) - goto out_err; +/** + Create a new OBEX instance + \param transport Which transport to use. + \param eventcb Function pointer to your event callback. + \param flags Bitmask of flags. The following flags can be used here: + - #OBEX_FL_KEEPSERVER : Keep the server alive after incomming request + - #OBEX_FL_FILTERHINT : Filter target devices based on Obex hint bit + - #OBEX_FL_FILTERIAS : Filter target devices based on IAS entry + - #OBEX_FL_CLOEXEC : Open all sockets with SO_CLOEXEC set + - #OBEX_FL_NONBLOCK : Open all sockets non-blocking + \return an OBEX handle or NULL on error. + */ +LIB_SYMBOL +obex_t * CALLAPI OBEX_New(enum obex_transport_type transport, + obex_event_cb_t eventcb, unsigned int flags) +{ + obex_t *self; - /* Allocate message buffers */ - /* It's safe to allocate them smaller than OBEX_MAXIMUM_MTU - * because buf_t will realloc data as needed. - Jean II */ - self->rx_msg = buf_new(self->mtu_rx); - if (self->rx_msg == NULL) - goto out_err; + obex_return_val_if_fail(eventcb != NULL, NULL); - self->tx_msg = buf_new(self->mtu_tx_max); - if (self->tx_msg == NULL) - goto out_err; + self = obex_new((enum obex_transport_type)transport, flags); + if (self) + self->eventcb = eventcb; return self; - -out_err: - OBEX_Cleanup(self); - return NULL; } /** @@ -223,6 +200,7 @@ void * CALLAPI OBEX_GetUserData(obex_t *self) /** Change user callback on an OBEX handle. + \deprecated Use OBEX_SetEventCb() instead. \param self OBEX handle \param eventcb Function pointer to your new event callback. \param data Pointer to the new user data to pass to the new @@ -235,6 +213,27 @@ void CALLAPI OBEX_SetUserCallBack(obex_t *self, obex_event_t eventcb, obex_return_if_fail(self != NULL); /* The callback can't be NULL */ if (eventcb != NULL) { + self->old_eventcb = eventcb; + /* Optionaly change the user data */ + if (data != NULL) + self->userdata = data; + } +} + +/** + Change event callback on an OBEX handle. + \param self OBEX handle + \param eventcb Function pointer to your new event callback. + \param data Pointer to the new user data to pass to the new + callback (optional) + */ +LIB_SYMBOL +void CALLAPI OBEX_SetEventCb(obex_t *self, obex_event_cb_t eventcb, + void *data) +{ + obex_return_if_fail(self != NULL); + /* The callback can't be NULL */ + if (eventcb != NULL) { self->eventcb = eventcb; /* Optionaly change the user data */ if (data != NULL) @@ -313,6 +312,7 @@ int CALLAPI OBEX_ServerRegister(obex_t *self, struct sockaddr *saddr, int addrle /** Accept an incoming connection. + \deprecated \param server OBEX handle \param eventcb Event callback for client (use NULL for same as server) \param data Userdata for client (use NULL for same as server) @@ -333,6 +333,38 @@ LIB_SYMBOL obex_t *CALLAPI OBEX_ServerAccept(obex_t *server, obex_event_t eventcb, void *data) { + obex_t * client = OBEX_Accept(server); + + if (client) { + if (eventcb == NULL) + eventcb = client->old_eventcb; + if (data == NULL) + data = client->userdata; + OBEX_SetUserCallBack(client, eventcb, data); + } + + return client; +} + +/** + Accept an incoming connection. + \param server OBEX handle + \return the client instance or NULL on error + + Create a new OBEX instance to handle the incomming connection. + The old OBEX instance will continue to listen for new connections. + The two OBEX instances become totally independant from each other. + + This function should be called after the library generates + an #OBEX_EV_ACCEPTHINT event to the user, but before the user + start to pull data out of the incomming connection. + + Using this function also requires that the OBEX handle was created + with the #OBEX_FL_KEEPSERVER flag set while calling #OBEX_New(). + */ +LIB_SYMBOL +obex_t *CALLAPI OBEX_Accept(obex_t *server) +{ obex_t *self; DEBUG(3, "\n"); @@ -355,15 +387,8 @@ obex_t *CALLAPI OBEX_ServerAccept(obex_t *server, obex_event_t eventcb, return NULL; /* Set callback and callback data as needed */ - if (eventcb != NULL) - self->eventcb = eventcb; - else - self->eventcb = server->eventcb; - - if (data != NULL) - self->userdata = data; - else - self->userdata = server->userdata; + self->eventcb = server->eventcb; + self->userdata = server->userdata; self->init_flags = server->init_flags; diff --git a/lib/obex.sym b/lib/obex.sym index 0c33b63..6483738 100644 --- a/lib/obex.sym +++ b/lib/obex.sym @@ -1,8 +1,10 @@ OBEX_Init +OBEX_New OBEX_Cleanup OBEX_SetUserData OBEX_GetUserData OBEX_SetUserCallBack +OBEX_SetEventCb OBEX_SetTransportMTU OBEX_GetFD OBEX_RegisterCTransport @@ -14,6 +16,7 @@ OBEX_CustomDataFeed OBEX_HandleInput OBEX_ServerRegister OBEX_ServerAccept +OBEX_Accept OBEX_Request OBEX_CancelRequest OBEX_SuspendRequest diff --git a/lib/obex_main.c b/lib/obex_main.c index 7444250..a009275 100644 --- a/lib/obex_main.c +++ b/lib/obex_main.c @@ -38,6 +38,7 @@ #include <stdio.h> #endif /* _WIN32 */ +#include <stdlib.h> #ifdef HAVE_BLUETOOTH #include "bluez_compat.h" @@ -52,11 +53,68 @@ #include <openobex/obex_const.h> -int obex_debug; -int obex_dump; +#ifndef OBEX_DEBUG +#define OBEX_DEBUG -1 +#endif +#ifndef OBEX_DUMP +#define OBEX_DUMP 0 +#endif + +int obex_debug = OBEX_DEBUG; +int obex_dump = OBEX_DUMP; #include "cloexec.h" +obex_t * obex_new(enum obex_transport_type transport, unsigned int flags) +{ + obex_t *self; + char *env; + + env = getenv("OBEX_DEBUG"); + if (env) + obex_debug = atoi(env); + + env = getenv("OBEX_DUMP"); + if (env) + obex_dump = atoi(env); + + self = calloc(1, sizeof(*self)); + if (self == NULL) + return NULL; + + self->init_flags = flags; + self->mode = OBEX_MODE_SERVER; + self->state = STATE_IDLE; + self->rsp_mode = OBEX_RSP_MODE_NORMAL; + + /* Safe values. + * Both self->mtu_rx and self->mtu_tx_max can be increased by app + * self->mtu_tx will be whatever the other end sends us - Jean II */ + self->mtu_rx = OBEX_DEFAULT_MTU; + self->mtu_tx = OBEX_MINIMUM_MTU; + self->mtu_tx_max = OBEX_DEFAULT_MTU; + + if (obex_transport_init(self, transport) < 0) + goto out_err; + + /* Allocate message buffers */ + /* It's safe to allocate them smaller than OBEX_MAXIMUM_MTU + * because buf_t will realloc data as needed. - Jean II */ + self->rx_msg = buf_new(self->mtu_rx); + if (self->rx_msg == NULL) + goto out_err; + + self->tx_msg = buf_new(self->mtu_tx_max); + if (self->tx_msg == NULL) + goto out_err; + + return self; + +out_err: + OBEX_Cleanup(self); + return NULL; +} + /* * Function obex_create_socket() * @@ -195,7 +253,13 @@ void obex_deliver_event(obex_t *self, int event, int cmd, int rsp, int del) if (del == TRUE) self->object = NULL; - self->eventcb(self, object, self->mode, event, cmd, rsp); + if (self->eventcb) + self->eventcb(self, object, self->mode, event, cmd, rsp); + + else if (self->old_eventcb) + self->old_eventcb(self, object, (int)self->mode, (int)event, + (int)cmd, (int)rsp); + if (del == TRUE) obex_object_delete(object); diff --git a/lib/obex_main.h b/lib/obex_main.h index 24d37c5..82fea37 100644 --- a/lib/obex_main.h +++ b/lib/obex_main.h @@ -52,7 +52,9 @@ struct obex { struct databuffer *rx_msg; /* Reusable receive message */ struct obex_object *object; /* Current object being transfered */ - obex_event_t eventcb; /* Event-callback */ + + obex_event_t old_eventcb; /* Old, deprecated event-callback */ + obex_event_cb_t eventcb; /* Event-callback */ obex_transport_t trans; /* Transport being used */ @@ -62,6 +64,7 @@ struct obex { void * userdata; /* For user */ }; +obex_t * obex_new(enum obex_transport_type transport, unsigned int flags); socket_t obex_create_socket(struct obex *self, int domain); socket_t obex_create_packet_socket(obex_t *self, int domain); int obex_delete_socket(struct obex *self, socket_t fd); -- 1.7.5.4 ------------------------------------------------------------------------------ AppSumo Presents a FREE Video for the SourceForge Community by Eric Ries, the creator of the Lean Startup Methodology on "Lean Startup Secrets Revealed." This video shows you how to validate your ideas, optimize your ideas and identify your business strategy. http://p.sf.net/sfu/appsumosfdev2dev _______________________________________________ Openobex-users mailing list Openobex-users@lists.sourceforge.net http://lists.sourceforge.net/lists/listinfo/openobex-users