📄 obex.c
字号:
/********************************************************************* * * Filename: obex.c * Version: 0.9 * Description: API to be used by applications wanting to use OBEX * Status: Stable. * Author: Dag Brattli <dagb@cs.uit.no> * Created at: Sat Apr 17 16:50:25 1999 * CVS ID: $Id: obex.c,v 1.23 2001/02/27 14:24:14 pof Exp $ * * Copyright (c) 1999, 2000 Dag Brattli, All Rights Reserved. * Copyright (c) 1999, 2000 Pontus Fuchs, All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ********************************************************************/#include <config.h>#include <string.h>#include <errno.h>#ifdef _WIN32#include <winsock.h>#define ESOCKTNOSUPPORT 1#else /* _WIN32 */#include <fcntl.h>#include <signal.h>#include <unistd.h>#endif#include "obex_main.h"#include "obex_object.h"#include "obex_connect.h"#include "obex_client.h"#ifdef HAVE_IRDA#include "irobex.h"#endif/** * OBEX_Init - Initialize OBEX. * @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 * %OBEX_TRANS_CUST : Use user provided transport * If you use %OBEX_TRANS_CUST you must register your own * transport with OBEX_RegisterCTransport() * @eventcb: Function pointer to your event callback. * See obex.h for prototype of this callback. * @flags: Bitmask of flags. The following flags are available : * %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 * * Returns an OBEX handle or %NULL on error. */obex_t *OBEX_Init(gint transport, obex_event_t eventcb, guint flags){ obex_t *self;#ifdef OBEX_DEBUG obex_debug = OBEX_DEBUG;#endif g_return_val_if_fail(eventcb != NULL, NULL);#ifdef _WIN32 { WSADATA WSAData; if (WSAStartup (MAKEWORD(2,0), &WSAData) != 0) { g_message("WSAStartup failed\n"); return NULL; } }#endif self = g_new0(obex_t, 1); if (self == NULL) return NULL; self->eventcb = eventcb; self->keepserver = (flags & OBEX_FL_KEEPSERVER) ? TRUE : FALSE; self->filterhint = (flags & OBEX_FL_FILTERHINT) ? TRUE : FALSE; self->filterias = (flags & OBEX_FL_FILTERIAS ) ? TRUE : FALSE; self->fd = -1; self->serverfd = -1; self->state = MODE_SRV | STATE_IDLE; /* Init transport */ self->trans.type = transport; self->trans.connected = FALSE; /* Allocate message buffers */ self->rx_msg = g_netbuf_new(OBEX_DEFAULT_MTU); if (self->rx_msg == NULL) goto out_err; self->tx_msg = g_netbuf_new(OBEX_DEFAULT_MTU); if (self->tx_msg == NULL) goto out_err; self->mtu_rx = OBEX_DEFAULT_MTU; self->mtu_tx = OBEX_MINIMUM_MTU;#ifndef _WIN32 /* Ignore SIGPIPE. Otherwise send() will raise it and the app will quit */ signal(SIGPIPE, SIG_IGN);#endif return self;out_err: if (self->tx_msg != NULL) g_netbuf_free(self->tx_msg); if (self->rx_msg != NULL) g_netbuf_free(self->rx_msg); g_free(self); return NULL;}/** * OBEX_RegisterCTransport - Register a custom transport * @self: OBEX handle * @ctrans: Structure with callbacks to transport operations * (see obex_const.h for details) * * Call this function directly after OBEX_Init if you are using * a custom transport. */gint OBEX_RegisterCTransport(obex_t *self, obex_ctrans_t *ctrans){ g_return_val_if_fail(self != NULL, -1); g_return_val_if_fail(ctrans != NULL, -1); memcpy(&self->ctrans, ctrans, sizeof(obex_ctrans_t)); return 1;}/** * OBEX_Cleanup - Close down an OBEX instance * @self: OBEX handle * * Close down an OBEX instance. */void OBEX_Cleanup(obex_t *self){ g_return_if_fail(self != NULL); obex_transport_disconnect_request(self); obex_transport_disconnect_server(self); if (self->tx_msg) g_netbuf_free(self->tx_msg); if (self->rx_msg) g_netbuf_free(self->rx_msg); g_free(self);}/** * OBEX_SetUserData - Set userdata of an OBEX handle * @self: OBEX handle * @data: It's all up to you! */void OBEX_SetUserData(obex_t *self, gpointer data){ g_return_if_fail(self != NULL); self->userdata=data;}/** * OBEX_GetUserData - Read the userdata from an OBEX handle * @self: OBEX handle * * Returns userdata */gpointer OBEX_GetUserData(obex_t *self){ g_return_val_if_fail(self != NULL, 0); return self->userdata;}/** * OBEX_SetUserCallBack - Change user callback on an OBEX handle * @self: OBEX handle * @eventcb: Function pointer to your new event callback. * @data: Pointer to the new user data to pass to the new callback (optional) */void OBEX_SetUserCallBack(obex_t *self, obex_event_t eventcb, gpointer data){ g_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) self->userdata = data; }}/** * OBEX_ServerRegister - Start listening for incoming connections * @self: OBEX handle * @service: Service to bind to. Only used then using IrDA transport. * * Returns -1 on error. */gint OBEX_ServerRegister(obex_t *self, const char *service){ DEBUG(3, G_GNUC_FUNCTION "()\n"); g_return_val_if_fail(self != NULL, -1); g_return_val_if_fail(service != NULL, -1); return obex_transport_listen(self, service);}/** * OBEX_ServerAccept - Accept an incoming connection * @server: OBEX handle * @eventcb: Event callback for client (use %NULL for same as server) * @data: Userdata for client (use %NULL for same as server) * * 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_Init(). * * Returns the client instance or %NULL for error. */obex_t *OBEX_ServerAccept(obex_t *server, obex_event_t eventcb, gpointer data){ obex_t *self; DEBUG(3, G_GNUC_FUNCTION "()\n"); g_return_val_if_fail(server != NULL, NULL); /* We can accept only if both the server and the connection socket * are active */ if((server->fd <= 0) || (server->serverfd <= 0)) return(NULL); /* If we have started receiving something, it's too late... */ if(server->object != NULL) return(NULL); /* Allocate new instance */ self = g_new0(obex_t, 1); if (self == NULL) 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->keepserver = server->keepserver; /* Copy transport data */ memcpy(&self->trans, &server->trans, sizeof(obex_transport_t)); memcpy(&self->ctrans, &server->ctrans, sizeof(obex_ctrans_t)); self->mtu_rx = server->mtu_rx; self->mtu_tx = server->mtu_tx; /* Allocate message buffers */ self->rx_msg = g_netbuf_new(self->mtu_rx); if (self->rx_msg == NULL) goto out_err; self->tx_msg = g_netbuf_new(self->mtu_tx); if (self->tx_msg == NULL) goto out_err; /* Now, that's the interesting bit ! * We split the sockets apart, one for each instance */ self->fd = server->fd; self->serverfd = -1; server->fd = -1; self->state = MODE_SRV | STATE_IDLE; return self;out_err: if (self->tx_msg != NULL) g_netbuf_free(self->tx_msg); if (self->rx_msg != NULL) g_netbuf_free(self->rx_msg); g_free(self); return NULL;}/** * OBEX_HandleInput - Let the OBEX parser do some work * @self: OBEX handle * @timeout: Maximum time to wait in seconds * * Let the OBEX parser read and process incoming data. If no data * is available this call will block. * * When a request has been sent or you are waiting for an incoming server- * request you should call this function until the request has finished. * * Like select() this function returns -1 on error, 0 on timeout or * positive on success. */gint OBEX_HandleInput(obex_t *self, gint timeout){ DEBUG(4, G_GNUC_FUNCTION "()\n"); g_return_val_if_fail(self != NULL, -1); return obex_transport_handle_input(self, timeout);}/** * OBEX_CustomDataFeed - Feed OBEX with data when using a custom transport * @self: OBEX handle * @inputbuf: Pointer to custom data * @actual: Length of buffer */gint OBEX_CustomDataFeed(obex_t *self, guint8 *inputbuf, gint actual){ DEBUG(3, G_GNUC_FUNCTION "()\n"); g_return_val_if_fail(self != NULL, -1); g_return_val_if_fail(inputbuf != NULL, -1); return obex_data_indication(self, inputbuf, actual);}/** * OBEX_TransportConnect - Try to connect to peer * @self: OBEX handle * @saddr: Address to connect to * @addrlen: Length of address * * Returns -1 on error. */gint OBEX_TransportConnect(obex_t *self, struct sockaddr *saddr, int addrlen){ DEBUG(4, G_GNUC_FUNCTION "()\n"); g_return_val_if_fail(self != NULL, -1); g_return_val_if_fail(saddr != NULL, -1); memcpy(&self->trans.peer, saddr, addrlen); return obex_transport_connect_request(self);}/** * OBEX_TransportDisconnect - Disconnect transport * @self: OBEX handle */gint OBEX_TransportDisconnect(obex_t *self){ DEBUG(4, G_GNUC_FUNCTION "()\n"); g_return_val_if_fail(self != NULL, -1); obex_transport_disconnect_request(self);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -