/*
 * Copyright (c) 2006 Bea Lam. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
//
//  BBBluetoothOBEXServer.h
//  LightAquaBlue
//
//  Implements the server side of an OBEX session over a Bluetooth transport.
//
//  Generally you will use BBBluetoothOBEXServer like this:
//    1. Call registerForChannelOpenNotifications:selector:withChannelID:direction:
//       in the IOBluetoothRFCOMMChannel class in order be notified whenever 
//       you receive a client connection on a particular RFCOMM channel ID.
//    2. When you are notified that a client has connected, use the provided
//       IOBluetoothRFCOMMChannel to create a a BBBluetoothOBEXServer
//       object, and then call run: on the object to start the server.
//
//  There is an example in examples/LightAquaBlue/SimpleOBEXServer that shows
//  how to use this class to run a basic OBEX server session.  
//



@interface BBBluetoothOBEXServer : NSObject

/*
 * Creates and returns a BBBluetoothOBEXServer.
 */
+ (id)serverWithIncomingRFCOMMChannel:(IOBluetoothRFCOMMChannel *)channel
                             delegate:(id)delegate;

/*
 * Initialises a BBBluetoothOBEXServer that will run on the given <channel>.
 * The <delegate> will be notified when events occur on the server.
 */
- (id)initWithIncomingRFCOMMChannel:(IOBluetoothRFCOMMChannel *)channel
                           delegate:(id)delegate;

/*
 * Starts the server. The server will now receive and process client requests.
 */
- (void)run;

/*
 * Closes the server. It cannot be started again after this.
 */
- (void)close;

/*
 * Sets <responseCode> to be the next response code to be sent for the current
 * request.
 *
 * Available response codes are listed in the OBEXOpCodeResponseValues enum in
 * <IOBluetooth/OBEX.h>. (Use the codes that end with "WithFinalBit".) For
 * example, you could set the response code to
 * kOBEXResponseCodeNotFoundWithFinalBit if a client requests a non-existent
 * file.
 */
- (void)setResponseCodeForCurrentRequest:(int)responseCode;

/*
 * Adds <responseHeaders> to the next response headers to be sent for the
 * current request.
 *
 * For example, OBEX servers commonly include a "Length" header when
 * responding to a Get request to indicate the size of the file to be
 * transferred.
 */
- (void)addResponseHeadersForCurrentRequest:(BBOBEXHeaderSet *)responseHeaders;

/*
 * Sets the server's delegate to <delegate>.
 */
- (void)setDelegate:(id)delegate;

/*
 * Returns the delegate for this server.
 */
- (id)delegate;

/*
 * Sets whether debug messages should be displayed (default is NO).
 */
+ (void)setDebug:(BOOL)debug;

@end

/* * This informal protocol describes the methods that can be implemented for a * BBBluetoothOBEXServer delegate. * * For each type of client request, there is a "...shouldHandle..." method * (e.g. server:shouldHandleConnectRequest:) that is called when the request * is received. If the delegate does not implement this method for a * particular type of request, the server will automatically refuse all * requests of this type with a "Not Implemented" response. */ @protocol BBBluetoothOBEXServerDelegate /* * Called when an error occurs on the server. <error> is an error code from * <IOBluetooth/OBEX.h> and <description> is a description of the error. */ - (void)server:(BBBluetoothOBEXServer *)server errorOccurred:(OBEXError)error description:(NSString *)description; /* * Called when a Connect request is received with the specified <requestHeaders>. * * This should return YES if the request should be allowed to continue, or NO * if the request should be refused. (By default, a request will be refused * with a 'Forbidden' response; call setResponseCodeForCurrentRequest: to set * a more specific response.) */ - (BOOL)server:(BBBluetoothOBEXServer *)server shouldHandleConnectRequest:(BBOBEXHeaderSet *)requestHeaders; /* * Called when the server finishes processing of a Connect request. */ - (void)serverDidHandleConnectRequest:(BBBluetoothOBEXServer *)server; /* * Called when a Disconnect request is received with the specified <requestHeaders>. * * This should return YES if the request should be allowed to continue, or NO * if the request should be refused. (By default, a request will be refused * with a 'Forbidden' response; call setResponseCodeForCurrentRequest: to set * a more specific response.) */ - (BOOL)server:(BBBluetoothOBEXServer *)server shouldHandleDisconnectRequest:(BBOBEXHeaderSet *)requestHeaders; /* * Called when the server finishes processing of a Disconnect request. */ - (void)serverDidHandleDisconnectRequest:(BBBluetoothOBEXServer *)server; /* * Called when a Put request is received with the specified <requestHeaders>. * * This should return an opened NSOutputStream if the request should be allowed * to continue, or nil if the request should be refused. (By default, a request * will be refused with a 'Forbidden' response; call * setResponseCodeForCurrentRequest: to set a more specific response.) * * Note the returned stream *must* be open, or the request will fail. */ - (NSOutputStream *)server:(BBBluetoothOBEXServer *)server shouldHandlePutRequest:(BBOBEXHeaderSet *)requestHeaders; /* * Called each time a chunk of data is received during a Put request. * The <length> indicates the number of bytes received, and <isLastPacket> is * set to YES if all the data has now been received and the server is about to * send the final response for the request. */ - (void)server:(BBBluetoothOBEXServer *)server didReceiveDataOfLength:(unsigned)length isLastPacket:(BOOL)isLastPacket; /* * Called when the server finishes processing of a Put request. The * <outputStream> is the stream originally provided from * server:shouldHandlePutRequest: and <aborted> is set to YES if the client * sent an Abort request to cancel the Put request before it was completed. */ - (void)server:(BBBluetoothOBEXServer *)server didHandlePutRequestForStream:(NSOutputStream *)outputStream requestWasAborted:(BOOL)aborted; /* * Called when a Put-Delete request is received with the specified <requestHeaders>. * * This should return YES if the request should be allowed to continue, or NO * if the request should be refused. (By default, a request will be refused * with a 'Forbidden' response; call setResponseCodeForCurrentRequest: to set * a more specific response.) */ - (BOOL)server:(BBBluetoothOBEXServer *)server shouldHandlePutDeleteRequest:(BBOBEXHeaderSet *)requestHeaders; /* * Called when the server finishes processing of a Put-Delete request. */ - (void)serverDidHandlePutDeleteRequest:(BBBluetoothOBEXServer *)server; /* * Called when a Get request is received with the specified <requestHeaders>. * * This should return an opened NSInputStream if the request should be allowed * to continue, or nil if the request should be refused. (By default, a request * will be refused with a 'Forbidden' response; call * setResponseCodeForCurrentRequest: to set a more specific response.) * * Note the returned stream *must* be open, or the request will fail. */ - (NSInputStream *)server:(BBBluetoothOBEXServer *)server shouldHandleGetRequest:(BBOBEXHeaderSet *)requestHeaders; /* * Called each time a chunk of data is sent during a Get request. * The <length> indicates the number of bytes sent. */ - (void)server:(BBBluetoothOBEXServer *)server didSendDataOfLength:(unsigned)length; /* * Called when the server finishes processing of a Get request. The * <outputStream> is the stream originally provided from * server:shouldHandleGetRequest: and <aborted> is set to YES if the client * sent an Abort request to cancel the Get request before it was completed. */ - (void)server:(BBBluetoothOBEXServer *)server didHandleGetRequestForStream:(NSInputStream *)inputStream requestWasAborted:(BOOL)aborted; /* * Called when a SetPath request is received with the specified <requestHeaders> * and SetPath <flags>. The first two bits of the flags are significant * for the SetPath operation: * - Bit 0 is set if the server should back up one level (i.e. "..") * before applying the requested path name * - Bit 1 is set if the server should respond with an error instead of * creating a directory if the specified directory does not exist * * This should return YES if the request should be allowed to continue, or NO * if the request should be refused. (By default, a request will be refused * with a 'Forbidden' response; call setResponseCodeForCurrentRequest: to set * a more specific response.) */ - (BOOL)server:(BBBluetoothOBEXServer *)server shouldHandleSetPathRequest:(BBOBEXHeaderSet *)requestHeaders withFlags:(OBEXFlags)flags; /* * Called when the server finishes processing of a SetPath request. */ - (void)serverDidHandleSetPathRequest:(BBBluetoothOBEXServer *)server; @end