?? obex.c
字號(hào):
/********************************************************************* * * 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.47 2006/05/25 18:09:41 zany 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 * ********************************************************************/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.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"#include "inobex.h"#ifdef HAVE_IRDA#include "irobex.h"#endif#ifdef HAVE_USB#include "usbobex.h"#endif#ifdef HAVE_BLUETOOTH#include "btobex.h"#else// This is to workaround compilation without Bluetooth support. - Jean IItypedef char *bdaddr_t;#endifvoid OBEX_FreeInterfaces(obex_t *self);/** * 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_CUSTOM : Use user provided transport * %OBEX_TRANS_BLUETOOTH: Use regular Bluetooth RFCOMM socket (need the BlueZ stack) * %OBEX_TRANS_USB: Use USB transport (libusb needed) * If you use %OBEX_TRANS_CUSTOM 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(int transport, obex_event_t eventcb, unsigned int flags){ obex_t *self;#if OBEX_DEBUG obex_debug = OBEX_DEBUG;#endif#if OBEX_DUMP obex_dump = OBEX_DUMP;#endif obex_return_val_if_fail(eventcb != NULL, NULL);#ifdef _WIN32 { WSADATA WSAData; if (WSAStartup (MAKEWORD(2,0), &WSAData) != 0) { DEBUG(4, "WSAStartup failed\n"); return NULL; } }#endif self = malloc(sizeof(obex_t)); if (self == NULL) return NULL; memset(self, 0, sizeof(obex_t)); 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->writefd = -1; self->state = MODE_SRV | STATE_IDLE; /* Init transport */ self->trans.type = transport; self->trans.connected = FALSE; /* 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 sneds us - Jean II */ /* Set MTU to the maximum, if using USB transport - Alex Kanavin */ if (transport == OBEX_TRANS_USB) { self->mtu_rx = OBEX_MAXIMUM_MTU; self->mtu_tx = OBEX_MINIMUM_MTU; self->mtu_tx_max = OBEX_MAXIMUM_MTU; } else { self->mtu_rx = OBEX_DEFAULT_MTU; self->mtu_tx = OBEX_MINIMUM_MTU; self->mtu_tx_max = OBEX_DEFAULT_MTU; } /* 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;#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) buf_free(self->tx_msg); if (self->rx_msg != NULL) buf_free(self->rx_msg); 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. */int OBEX_RegisterCTransport(obex_t *self, obex_ctrans_t *ctrans){ obex_return_val_if_fail(self != NULL, -1); obex_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){ obex_return_if_fail(self != NULL); obex_transport_disconnect_request(self); obex_transport_disconnect_server(self); if (self->tx_msg) buf_free(self->tx_msg); if (self->rx_msg) buf_free(self->rx_msg); OBEX_FreeInterfaces(self); 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, void * data){ obex_return_if_fail(self != NULL); self->userdata=data;}/** * OBEX_GetUserData - Read the userdata from an OBEX handle * @self: OBEX handle * * Returns userdata */void * OBEX_GetUserData(obex_t *self){ obex_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, 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) self->userdata = data; }}/** * OBEX_SetTransportMTU - Set MTU to be used for receive and transmit * @self: OBEX handle * @mtu_rx: maximum receive transport packet size * @mtu_tx_max: maximum transmit transport packet size negociated * * Changing those values can increase the performance of the underlying * transport, but will increase memory consumption and latency (especially * abort latency), and may trigger bugs in buggy transport. * This need to be set *before* establishing the connection. * * Returns -1 on error. */int OBEX_SetTransportMTU(obex_t *self, uint16_t mtu_rx, uint16_t mtu_tx_max){ obex_return_val_if_fail(self != NULL, -EFAULT); if (self->object) { DEBUG(1, "We are busy.\n"); return -EBUSY; } if (mtu_rx < OBEX_MINIMUM_MTU /*|| mtu_rx > OBEX_MAXIMUM_MTU*/) return -E2BIG; if (mtu_tx_max < OBEX_MINIMUM_MTU /*|| mtu_tx_max > OBEX_MAXIMUM_MTU*/) return -E2BIG; /* Change MTUs */ self->mtu_rx = mtu_rx; self->mtu_tx_max = mtu_tx_max; /* Reallocate transport buffers */ buf_resize(self->rx_msg, self->mtu_rx); if (self->rx_msg == NULL) return -ENOMEM; buf_resize(self->tx_msg, self->mtu_tx_max); if (self->tx_msg == NULL) return -ENOMEM; return 0;}/** * OBEX_ServerRegister - Start listening for incoming connections * @self: OBEX handle * @saddr: Local address to bind to * @addrlen: Length of address * * Bind a server socket to an Obex service. Common transport have * specialised version of this function. * Note : between 0.9.8 and 0.10.0, the prototype of this function * changed to make it generic. If you want your code to work across * new and old version of OpenObex, you may use #ifdef OBEX_MAXIMUM_MTU * to test the Obex version. * * Returns -1 on error. */int OBEX_ServerRegister(obex_t *self, struct sockaddr *saddr, int addrlen){ DEBUG(3, "\n"); obex_return_val_if_fail(self != NULL, -1); obex_return_val_if_fail((addrlen == 0) || (saddr != NULL), -1); memcpy(&self->trans.self, saddr, addrlen); return obex_transport_listen(self);}/** * 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, void * data){ obex_t *self; DEBUG(3, "\n"); obex_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 = malloc(sizeof(obex_t)); if (self == NULL) return(NULL); memset(self, 0, sizeof(obex_t)); /* 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; self->mtu_tx_max = server->mtu_tx_max; /* Allocate message buffers */ self->rx_msg = buf_new(self->mtu_rx); if (self->rx_msg == NULL) goto out_err; /* Note : mtu_tx not yet negociated, so let's be safe here - Jean II */ self->tx_msg = buf_new(self->mtu_tx_max); if (self->tx_msg == NULL) goto out_err;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -