⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 obex_server.c

📁 这是Linux环境下的openobex
💻 C
字号:
/********************************************************************* *                 * Filename:      obex_server.c * Version:       0.8 * Description:   Handles server operations * Status:        Experimental. * Author:        Pontus Fuchs <pontus.fuchs@tactel.se> * Created at:    Thu Nov 11 20:55:00 1999 * CVS ID:        $Id: obex_server.c,v 1.16 2006/01/03 18:36:15 holtmann Exp $ * *     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 <stdlib.h>#include <stdio.h>#include <errno.h>#include "obex_main.h"#include "obex_header.h"#include "obex_connect.h"/* * Function obex_server () * *    Handle server-operations * */int obex_server(obex_t *self, GNetBuf *msg, int final){	obex_common_hdr_t *request;	int cmd, ret;	unsigned int len;		DEBUG(4, "\n");	request = (obex_common_hdr_t *) msg->data;	cmd = request->opcode & ~OBEX_FINAL;	len = ntohs(request->len);		switch(self->state & ~MODE_SRV)	{	case STATE_IDLE:		/* Nothing has been recieved yet, so this is probably a new request */		DEBUG(4, "STATE_IDLE\n");				if(self->object) {			/* What shall we do here? I don't know!*/			DEBUG(0, "Got a new server-request while already having one!\n");			obex_response_request(self, OBEX_RSP_INTERNAL_SERVER_ERROR);			return -1;		}		self->object = obex_object_new();		if(self->object == NULL) {			DEBUG(1, "Allocation of object failed!\n");			obex_response_request(self, OBEX_RSP_INTERNAL_SERVER_ERROR);			return -1;		}		/* Remember the initial command of the request.*/		self->object->cmd = cmd;		/* Hint app that something is about to come so that		   the app can deny a PUT-like request early, or		   set the header-offset */		obex_deliver_event(self, OBEX_EV_REQHINT, cmd, 0, FALSE);								/* Some commands needs special treatment (data outside headers) */		switch(cmd)	{		case OBEX_CMD_CONNECT:			DEBUG(4, "Got CMD_CONNECT\n");			/* Connect needs some extra special treatment */			if(obex_parse_connect_header(self, msg) < 0) {				obex_response_request(self, OBEX_RSP_BAD_REQUEST);				obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);				return -1;			}			self->object->headeroffset = 4;			break;		case OBEX_CMD_SETPATH:			self->object->headeroffset = 2;			break;		}		self->state = MODE_SRV | STATE_REC;		// no break! Fallthrough */		case STATE_REC:		DEBUG(4, "STATE_REC\n");		/* In progress of receiving a request */				/* Abort? */		if(cmd == OBEX_CMD_ABORT) {			DEBUG(1, "Got OBEX_ABORT request!\n");			obex_deliver_event(self, OBEX_EV_ABORT, self->object->opcode, cmd, TRUE);			obex_response_request(self, OBEX_RSP_SUCCESS);			/* This is not an Obex error, it is just that the peer			 * aborted the request, so return 0 - Jean II */			return 0;		}				/* Sanity check */		if(cmd != self->object->cmd) {			/* The cmd-field of this packet is not the			   same as int the first fragment. Bail out! */			obex_response_request(self, OBEX_RSP_BAD_REQUEST);			obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, cmd, TRUE);			return -1;		}				/* Get the headers... */		if(obex_object_receive(self, msg) < 0)	{			obex_response_request(self, OBEX_RSP_BAD_REQUEST);			obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);			return -1;		}				if(!final) {			/* As a server, the final bit is always SET- Jean II */			if(obex_object_send(self, self->object, FALSE, TRUE) < 0) {				obex_deliver_event(self, OBEX_EV_LINKERR, cmd, 0, TRUE);				return -1;			}						else {				obex_deliver_event(self, OBEX_EV_PROGRESS, cmd, 0, FALSE);			}			break; /* Stay in this state if not final */		}		else {			DEBUG(4, "We got a request!\n");			/* More connect-magic woodoo stuff */			if(cmd == OBEX_CMD_CONNECT)				obex_insert_connectframe(self, self->object);			/* Tell the app that a whole request has arrived. While			   this event is delivered the app should append the			   headers that should be in the response */			obex_deliver_event(self, OBEX_EV_REQ, cmd, 0, FALSE);			self->state = MODE_SRV | STATE_SEND;			len = 3; /* Otherwise sanitycheck later will fail */		}		/* Note the conditional fallthrough! */		case STATE_SEND:		/* Send back response */		DEBUG(4, "STATE_SEND\n");				/* Abort? */		if(cmd == OBEX_CMD_ABORT) {			DEBUG(1, "Got OBEX_ABORT request!\n");			obex_response_request(self, OBEX_RSP_SUCCESS);			obex_deliver_event(self, OBEX_EV_ABORT, self->object->opcode, cmd, TRUE);			/* This is not an Obex error, it is just that the peer			 * aborted the request, so return 0 - Jean II */			return 0;				}				if(len > 3) {			DEBUG(1, "STATE_SEND Didn't expect data from peer (%d)\n", len);			DUMPBUFFER(4, "unexpected data", msg);			/* At this point, we are in the middle of sending			 * our response to the client, and it is still			 * sending us some data ! This break the whole			 * Request/Response model of HTTP !			 * Most often, the client is sending some out of band			 * progress information for a GET.			 * This is the way we will handle that :			 * Save this header in our Rx header list. We can have			 * duplicated header, so no problem...			 * The user has already parsed headers, so will most			 * likely ignore those new headers.			 * User can check the header in the next EV_PROGRESS,			 * doing so will hide the header (until reparse).			 * If not, header can be parsed at 'final'.			 * Don't send any additional event to the app to not			 * break compatibility and because app can just check			 * this condition itself...			 * No headeroffset needed because 'connect' is			 * single packet (or we deny it).			 * Jean II */			if((cmd == OBEX_CMD_CONNECT) ||			   (obex_object_receive(self, msg) < 0))	{				obex_response_request(self, OBEX_RSP_BAD_REQUEST);				obex_deliver_event(self, OBEX_EV_PARSEERR, self->object->opcode, 0, TRUE);				return -1;			}			obex_deliver_event(self, OBEX_EV_UNEXPECTED, self->object->opcode, 0, FALSE);			/* Note : we may want to get rid of received header,			 * however they are mixed with legitimate headers,			 * and the user may expect to consult them later.			 * So, leave them here (== overhead). Jean II */		}						/* As a server, the final bit is always SET, and the		 * "real final" packet is distinguish by beeing SUCCESS		 * instead of CONTINUE.		 * It doesn't make sense to me, but that's the spec.		 * See Obex spec v1.2, chapter 3.2, page 21 and 22.		 * See also example on chapter 7.3, page 47.		 * So, force the final bit here. - Jean II */		ret = obex_object_send(self, self->object, TRUE, TRUE);		if(ret == 0) {			/* Made some progress */			obex_deliver_event(self, OBEX_EV_PROGRESS, cmd, 0, FALSE);		}		else if(ret < 0) {			/* Error sending response */			obex_deliver_event(self, OBEX_EV_LINKERR, cmd, 0, TRUE);			return -1;		}		else {			/* Response sent! */			if(cmd == OBEX_CMD_DISCONNECT)	{				DEBUG(2, "CMD_DISCONNECT done. Resetting MTU!\n");				self->mtu_tx = OBEX_MINIMUM_MTU;			}			obex_deliver_event(self, OBEX_EV_REQDONE, cmd, 0, TRUE); 			self->state = MODE_SRV | STATE_IDLE;		}		break;		default:		DEBUG(0, "Unknown state\n");		obex_response_request(self, OBEX_RSP_BAD_REQUEST);		obex_deliver_event(self, OBEX_EV_PARSEERR, cmd, 0, TRUE);		return -1;	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -