#ifndef _OI_OBEXSRV_H
#define _OI_OBEXSRV_H

/**
 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
  @file
  This file provides the API for the server side of the Generic Object Exchange Profile.
 */

#include "oi_stddefs.h"
#include "oi_status.h"
#include "oi_obex.h"
#include "oi_obexspec.h"
#include "oi_connect_policy.h"
#include "oi_bt_profile_config.h"

/** \addtogroup OBEX */
/**@{*/

#ifdef __cplusplus
extern "C" {
#endif


/**
 * OBEX registered server required authentication
 */
typedef enum {
    OI_OBEXSRV_AUTH_NONE = 0,
    OI_OBEXSRV_AUTH_PASSWORD,
    OI_OBEXSRV_AUTH_USERID_AND_PASSWORD
} OI_OBEXSRV_AUTHENTICATION;


/**
 *  represents an active connection to a remote OBEX client
 */
typedef OI_OBEX_CONNECTION_HANDLE OI_OBEXSRV_CONNECTION_HANDLE;


/**
 * A callback function of this type indicates that a client is attempting to connect to this server.
 * The application must call OI_OBEXSRV_AcceptConnect() to accept or reject the incoming connection.
 *
 * @param connectionId     A unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param unauthorized     If TRUE indicates that this connection requires
 *                         authentication and the application must call back
 *                         with a password.
 *
 * @param userId           If unauthorized is TRUE the client may have provided
 *                         a user id. In case of client-initiated authentication
 *                         the value of user id is NULL.
 *
 * @param userIdLen        length of the user id.
 *
 * @param realm            Indicates the realm received in Client's challenge or NULL
 *
 */

typedef void (*OI_OBEXSRV_CONNECT_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                       OI_BOOL                      unauthorized,
                                       OI_BYTE                      *userId,
                                       OI_UINT8                     userIdLen,
                                       OI_OBEX_REALM                *realm);

/**
 * A callback function of this type indicates that a client is disconnecting from this server.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 */

typedef void (*OI_OBEXSRV_DISCONNECT_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId);


/**
 * A callback function of this type indicates that a GET command has been received
 * from a connected OBEX client.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param cmdHeaders       This parameter is a pointer to a list of OBEX headers
 *                         accompanying the get command.  This list may be NULL
 *                         if the GET command is simply requesting the next
 *                         packet.
 *
 * @param status           OI_OBEX_CONTINUE indicates the client is ready for
 *                         data; the upper layer server should respond with
 *                         OI_OBEXSRV_GetResponse(connectionId, <ARG>, OI_OK).
 *
 *                         OI_OBEXSRV_INCOMPLETE_GET indicates that the client
 *                         will respond with more information about the request
 *                         in a subsequent packet; the server should respond
 *                         with OI_OBEXSRV_GetResponse(connectionId, <ARG>,
 *                         OI_OBEX_CONTINUE)
 *
 *                         Any other status indicates that the transaction is
 *                         complete, successfully or otherwise.
 *
 * @return                a status code to indicate whether the get request is accepted or
 *                        rejected
 */

typedef OI_STATUS (*OI_OBEXSRV_GET_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                        OI_OBEX_HEADER_LIST *cmdHeaders,
                                        OI_STATUS status);

/**
 * A callback function of this type returns buffers to the upper layer and indicates that OBEX is
 * requesting bulk data to send in response to a GET request.
 *
 * @param connectionId    This parameter is a unique ID that represents an established connection
 *                        to an OBEX server.
 *
 * @param numBuffers      The number of buffers being releases by this call. This parameter will be
 *                        zero if this is the first bulk data get indication.
 *
 * @param bulkDataBuffer  This parameter is an array of pointers to data buffers that are not longer
 *                        being used by OBEX. Memory for these buffers was allocated by the caller
 *                        to OI_OBEXSRV_BulkGetResponse() and can now be freed or reused by the caller.
 *
 * @param bufferLen       This parameter is an array of lengths of data buffers being returned.
 *
 * @param status        - OI_OK if the GET transaction has completed successfuly.
 *                      - OI_OBEX_CONTINUE indicates that OBEX is ready for more data, the upper
 *                        layer server should call OI_OBEXSRV_GetBulkResponse().
 *                      - Error status code indicating that the GET transaction is canceled.
 */

typedef OI_STATUS (*OI_OBEXSRV_BULK_GET_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                             OI_UINT8 numBuffers,
                                             OI_UINT8 *bulkDataBuffer[],
                                             OI_UINT32 bufferLen[],
                                             OI_STATUS status);

/**
 *
 * A callback function of this type indicates that a PUT request has been
 * received from a connected OBEX client.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param headers          This parameter is a pointer to a list of OBEX headers
 *                         in the put request. This will be NULL if the put
 *                         operation has been aborted by the client or if the
 *                         final cleanup callback is being invoked.
 *
 * @param status           OI_OK if this is the final put request and to signal the
 *                         cleanup callback; OI_OBEX_CONTINUE if there is more
 *                         data to come; or an error status.
 *
 * @return                a status code to indicate whether the put request is
 *                        accepted or rejected.
 */

typedef OI_STATUS (*OI_OBEXSRV_PUT_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                        OI_OBEX_HEADER_LIST *headers,
                                        OI_STATUS status);


/**
 * A callback function of this type indicates the path set for get and put operations.
 *
 * @param connectionId   a unique identifier generated by the OBEX server that
 *                       identifies the connection
 *
 * @param folder         a unicode string for the folder that be NULL
 *
 * @param upLevel        indicates that the path is being set to the parent folder of
 *                       the current folder (equivalent to '..')
 *
 * @param create         indicates that a new folder should be created if required and
 *                       access permissions allow
 *
 * @return              a status code to indicate if the setpath request is
 *                      accepted or rejected.
 */

typedef OI_STATUS (*OI_OBEXSRV_SET_PATH_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                             OI_OBEX_UNICODE *folder,
                                             OI_BOOL upLevel,
                                             OI_BOOL create);


/**
 *
 * A callback function of this type indicates that an ACTION request has been
 * received from a connected OBEX client.
 *
 * @param connectionId     A unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param actionId         Identifies the action to be performed.
 *
 * @param objectName       Name of the object to perform the action on.
 *
 * @param headers          This parameter is a pointer to a list of OBEX headers
 *                         in the Action request.
 *
 * @param status           OI_OK if this is the final put request and to signal the
 *                         cleanup callback; OI_OBEX_CONTINUE if there is more
 *                         data to come; or an error status.
 *
 * @return                a status code to indicate whether the Action request is
 *                        accepted or rejected.
 */

typedef OI_STATUS (*OI_OBEXSRV_ACTION_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                           OI_UINT8 actionId,
                                           OI_OBEX_UNICODE *name,
                                           OI_OBEX_HEADER_LIST *headers);

/**
 * A callback function of this type can be provided when a server is registered to allow an
 * upper layer to monitor progress of PUT and GET operations.
 *
 * @param connectionId     a unique ID that represents the in-progress connection
 *
 * @param obexCmd          Indicates if this is a put (OI_OBEX_CMD_PUT) or a get (OI_OBEX_CMD_GET)
 *
 * @param progressBytes    A running count of the number or bytes transferred.
 */
typedef void (*OI_OBEXSRV_PROGRESS_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                        OI_UINT8 obexCmd,
                                        OI_UINT32 progressBytes);


/**
 * A callback function of this type indicates that authentication is required on an inbound
 * connection. The application must call OI_OBEXSRV_AuthAccept() to accept or reject the connect
 * request.
 *
 * @param connectionId     A unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param addr             The Bluetooth device address of the connecting client
 *
 */

typedef void (*OI_OBEXSRV_AUTH_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                    OI_BD_ADDR *addr);

/**
 * A callback function of this type indicates that the server has received an abort
 * command from the client.  Application must call OBEXSRV_AbortResponse to send
 * response to the abort command.
 *
 * @note    Note that this callback should only concern itself with sending a response
 *          to the abort.  Specifically, the callback should NOT concern itself with the
 *          operation in progress.  The BM3 OBEX server will manage the termination of
 *          current operation, calling all the appropriate callbacks with failed status.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param cmdHeaders       This parameter is a pointer to a list of OBEX headers
 *
 */
typedef void (*OI_OBEXSRV_ABORT_IND)(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                     OI_OBEX_HEADER_LIST          *cmdHeaders);


/**
  This structure lists callback functions for handling server
  requests.
  */
typedef struct {
    OI_OBEXSRV_CONNECT_IND connectInd;       /**< Client is attempting to connect. */
    OI_OBEXSRV_DISCONNECT_IND disconnectInd; /**< Client is disconnecting. */
    OI_OBEXSRV_GET_IND getInd;               /**< GET request received from client. */
    OI_OBEXSRV_PUT_IND putInd;               /**< PUT request received from client. */
    OI_OBEXSRV_SET_PATH_IND setPathInd;      /**< SETPATH request received from client. */
    OI_OBEXSRV_BULK_GET_IND bulkGetInd;      /**< GET request received from client. May be NULL if bulk get
                                               responses are not supported by the upper layer profile */
    OI_OBEXSRV_ACTION_IND actionInd;         /**< ACTION request received from client. May be NULL if action
                                               operations are not supported by upper layer profile. */
    OI_OBEXSRV_PROGRESS_IND progressInd;     /**< Reports progress of PUTs and GETs. May be NULL */
    OI_OBEXSRV_AUTH_IND authInd;             /**< Indicates an incoming connect request to a server
                                               that requires authentication. This function is
                                               optional and is supplied gives the application an
                                               early opportunity to reject an incoming connect
                                               request or provide realm information required for the
                                               authentication phase. */
    OI_OBEXSRV_ABORT_IND abortInd;          /**< Client has requested to abort the current operation;
                                               may be NULL. */
} OI_OBEXSRV_CB_LIST;



/**
 * Function called by upper layer to accept or reject a connect request.
 *
 * @param connectionHandle OBEX server connection handle for the connection
 *                         being accepted.
 *
 * @param accept           TRUE if the upper layer accepts the connect request.
 *
 * @param status           Reason for the refusal, e.g "out of resources".
 *
 * @param optHeaders       Optional headers to include in the connect response.
 *                         NULL indicates there are no optional headers.
 *
 * @return                 OI_OK if the confirmation was appropriate and the
 *                         connection handle is still valid.
 */

OI_STATUS OI_OBEXSRV_AcceptConnect(OI_OBEXSRV_CONNECTION_HANDLE connectionHandle,
                                   OI_BOOL                      accept,
                                   OI_STATUS                    status,
                                   const OI_OBEX_HEADER_LIST    *optHeaders);


/**
 * Function called to confirm that the path has been set in response to a
 * setpath indication.
 *
 * @param connectionHandle OBEX server connection handle for the service request
 *                         being acknowledged.
 *
 * @param status           Status code indicating if the request was accepted
 *                         and completed, was rejected, or failed.
 *
 * @param optHeaders       Optional headers to include in the confirm response.
 *                         NULL indicates there are no optional headers.
 *
 * @return                 OI_OK if the confirmation was appropriate and could
 *                         be sent.
 */

OI_STATUS OI_OBEXSRV_ConfirmSetpath(OI_OBEXSRV_CONNECTION_HANDLE    connectionHandle,
                                    OI_STATUS                       status,
                                    const OI_OBEX_HEADER_LIST        *optHeaders);

/**
 * This functions gets the connection target associated with an OBEX server
 * connection handle. If no target was used to connect, target->data is set to
 * NULL and target->len to zero.
 *
 * @param connectionHandle OBEX server connection handle for which the current
 *                         target is desired
 *
 * @param target    pointer to caller's variable where information about the
 *                  target will be stored.
 *
 * @return
 *      - OI_OK: A connection exists. The target has been placed into the
 *        caller's variable.
 *      - OI_OBEX_NOT_CONNECTED: connectionHandle is not associated with a valid
 *        OBEX connection. The callers' variable is unchanged.
 */

OI_STATUS OI_OBEXSRV_GetTarget(OI_OBEXSRV_CONNECTION_HANDLE connectionHandle,
                               OI_OBEX_BYTESEQ *target);


/**
 * This function gets the Bluetooth Device Address (BD_ADDR) associated with an
 * OBEX server connection handle.
 *
 * @param connectionHandle OBEX server connection handle for which a BD_ADDR is desired
 *
 * @param pBdAddr pointer to caller's variable where the BD_ADDR will be stored
 *
 * @return
 *      - OI_OK: A connection exists. The BD_ADDR has been placed into the
 *        caller's variable.
 *      - OI_OBEX_NOT_CONNECTED: connectionHandle is not associated with a valid
 *        OBEX connection. The callers' variable is unchanged.
 *
 */
OI_STATUS OI_OBEXSRV_GetClientAddr(OI_OBEXSRV_CONNECTION_HANDLE connectionHandle,
                                   OI_BD_ADDR *pBdAddr);

/**
 * This function gets the lower layer protocol info associated with an OBEX server connection handle.
 *
 * @param connectionHandle OBEX server connection handle for which a lower layer
 *                         service id is desired
 *
 * @param lowerProtocol    Pointer to caller's variable where the protocol information
 *                         will be stored
 *
 * @return
 *      - OI_OK: A connection exists. The service is has been placed into
 *        the caller's variable.
 *      - OI_OBEX_NOT_CONNECTED: connectionHandle is not associated with a valid
 *        OBEX connection. The callers' variable is unchanged.
 */
OI_STATUS OI_OBEXSRV_GetLowerProtocolInfo(OI_OBEXSRV_CONNECTION_HANDLE connectionHandle,
                                          OI_OBEX_LOWER_PROTOCOL *lowerProtocol);


/**
 * Accept or reject and authenticated connection. This function must be called in response to an
 * OI_OBEXSRV_AUTH_IND callback.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param realm            The realm for authentication - may be NULL.
 *
 * @param accept           TRUE to accept the connection, FALSE to reject the connection.
 *
 * @return                 OI_OK or an error status if this function was called
 *                         at an inappropriate wrong time.
 */
OI_STATUS OI_OBEXSRV_AuthAccept(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                const OI_OBEX_REALM          *realm,
                                OI_BOOL                      accept);

/**
 * Response to an connect indication that reported that the connection was
 * unauthorized. If the password is correct and authentication completes another
 * connect indication will be issued.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param userId           the user id for the connecting user. If the routine is called in response
 *                         to a authentication challenge from a client, this parameter should be set
 *                         to a User Id provided by the server.
 *                         If the routine is called to handle authentication response from a client,
 *                         this parameter would hold a User Id provided by the client.
 *
 * @param userIdLen        Length of the userId.
 *
 * @param password         This parameter is a pointer to a NULL-terminated
 *                         password.  A NULL value indicates that the
 *                         application is rejecting the authentication
 *                         challenge.
 *
 * @param readOnly         indicates that the application is granting read-only
 *                         access only.
 *
 * @return                 OI_OK or an error status if this function was called
 *                         at an inappropriate wrong time.
 */
OI_STATUS OI_OBEXSRV_AuthenticationResponse(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                            const OI_BYTE *userId,
                                            OI_UINT8 userIdLen,
                                            const OI_CHAR *password,
                                            OI_BOOL readOnly);
/**
 * Respond to a GET command by sending data to a connected OBEX client.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param rspHeaders       This parameter is a pointer to a list of OBEX headers
 *                         that contain the response to the get command. If the
 *                         return status is OI_OK, the application must not free
 *                         any memory referenced by the headers until the next
 *                         get indication callback is invoked
 *
 * @param rspStatus        OI_OBEX_CONTINUE if there is more data to get; OI_OK
 *                         if this is no more data; or an error status.
 *
 * @return                OI_OK or an error status if the response could not be sent.
 */
OI_STATUS OI_OBEXSRV_GetResponse(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                 OI_OBEX_HEADER_LIST *rspHeaders,
                                 OI_STATUS rspStatus);


/**
 * Send bulk data to an OBEX client in response to a get request. This function is only called if
 * the upper layer registered support for bulk data gets by registering a OI_OBEXSRV_BULK_GET_IND
 * callback. The OBEX server will segment the bulk data provided by the caller into appropriately
 * sized OBEX packets. Unlike OI_OBEXCLI_GetReponse() which requires a get indication for each call,
 * multiple OI_OBEXCLI_BulkGetResponse() calls can be made in response to a single
 * OI_OBEXSRV_BulkGetInd() and OBEX will queue the data internally. This is of most value when the
 * connection has been configured for single response mode because it allows OBEX to keep data
 * flowing. A OI_OBEXSRV_BULK_GET_IND callback is called as each bulk data buffer has been
 * sent to the client For a specific GET transaction, once this function has been called, the
 * transaction must be completed using this function.
 *
 * Note that the OBEX server segments bulk data blocks to fit within the negotiation OBEX packet
 * size but will not aggregate small blocks into a larger OBEX packet.
 *
 * @param connectionId    This parameter is a unique ID that represents an established connection to
 *                        a remote OBEX client.
 *
 * @param numBuffers      The number of buffer to put.
 *
 * @param bulkDataBuffer  An array of bulk data buffers to be sent. The data buffers must not be
 *                        freed until the buffer pointers are individually returned in subsequent
 *                        OI_OBEXSRV_BULK_GET_IND calls.
 *
 * @param bufferLength    An array of sizes for the bulk data buffers. The bulk data buffers are
 *                        combined and segmented internally into appropriately sized OBEX packets so
 *                        this value can be arbitrarily large or small.
 *
 * @param status          Response status code:
 *                        - OI_OK indicates there is no more data to get.
 *                        - OI_OBEX_CONTINUE if there is more data to get
 *                        - An error status terminates the get transaction.
 *
 * @return                - OI_OK if data was successful but no more BulkGetResponses() are permitted at this time.
 *                        - OI_OBEX_CONTINUE if the get response was successful and more gets are permitted.
 *
 *                        - Other errors indicate that the get operation failed and that the caller
 *                          should cleanup and if necessary disconnect the link.
 */
OI_STATUS OI_OBEXSRV_BulkGetResponse(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                     OI_UINT8 numBuffers,
                                     OI_UINT8 *bulkDataBuffer[],
                                     OI_UINT32 bufferLength[],
                                     OI_STATUS rspStatus);

/**
 * Acknowledge a PUT command, optionally sending response headers to a connected
 * OBEX client.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param rspHeaders       This parameter is a pointer to a list of OBEX headers
 *                         that contain the response to the put command.  If the
 *                         server has no response headers to send, it should set
 *                         rspHeaders to NULL. Otherwise, if the return status
 *                         is OI_OK, then the application must not free any
 *                         memory referenced by the headers until the response
 *                         confirmation callback is invoked.
 *
 * @param rspStatus        should be the same as the status passed to
 *                         the server's PUT callback (OI_OK or OI_OBEX_CONTINUE)
 *                         if the operation was successful, or an error message
 *                         otherwise.
 */
OI_STATUS OI_OBEXSRV_PutResponse(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                 OI_OBEX_HEADER_LIST *rspHeaders,
                                 OI_STATUS rspStatus);


/**
 * Function called to report the result of an Action operation.
 *
 * @param connectionHandle OBEX server connection handle for the Action operation
 *                         being acknowledged.
 *
 * @param actionId         The action that the response is for.
 *
 * @param status           Status code indicating if the action operation was accepted
 *                         and completed, was rejected, or failed.
 *
 * @param optHeaders       Optional headers to include in the connect response.
 *                         NULL indicates there are no optional headers.
 *
 * @return                 OI_OK if the response was appropriate and could
 *                         be sent.
 */

OI_STATUS OI_OBEXSRV_ActionResponse(OI_OBEXSRV_CONNECTION_HANDLE    connectionHandle,
                                    OI_UINT8                        actionId,
                                    OI_STATUS                       status,
                                    const OI_OBEX_HEADER_LIST       *optHeaders);

/**
 * Acknowledge a Abort command, optionally sending response headers to OBEX client.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection
 *
 * @param rspHeaders       This parameter is a pointer to a list of OBEX headers
 *                         that contain the response to the abort command.
 *                         If the server has no response headers to send,
 *                         it should set rspHeaders to NULL.
 *
 * @param                  rspStatus - per spec, should be OI_OK.
 */

OI_STATUS OI_OBEXSRV_AbortResponse(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                   OI_OBEX_HEADER_LIST          *rspHeaders,
                                   OI_STATUS                    rspStatus);

/**
 * This function returns the optimal size for a body header for a connection.
 * Sending body headers that are smaller than this size or not an integer
 * multiple of this size will result in slower data transfer rates.
 *
 * @param connectionId    a unique identifier generated by the OBEX server that
 *                        identifies the connection
 *
 * @return                best  payload size or 0 if there is no connection
 */

OI_UINT16 OI_OBEXSRV_OptimalBodyHeaderSize(OI_OBEXSRV_CONNECTION_HANDLE connectionId);

/**
 * This function forcibly severs the connection from an OBEX client to the OBEX
 * server. The disconnect indication callback will be called when the disconnect
 * is complete.
 *
 * An OBEX server may need to forcibly terminate a connection during
 * deregistration, since deregistration will fail if a connection is in place.
 *
 * @param connectionId     a unique identifier generated by the OBEX server that
 *                         identifies the connection.
 *
 * @return                 OI_OK if the connectionId is valid and the connection
 *                         will be terminated.
 */

OI_STATUS OI_OBEXSRV_ForceDisconnect(OI_OBEXSRV_CONNECTION_HANDLE connectionId);

/**
 * This function registers an OBEX server to accept put and/or get requests from OBEX clients.
 *
 * @param target           a byte sequence that idenfifies the OBEX target for the
 *                         service being registered; may be NULL.
 *
 * @param CBList           pointer to a list of the application functions that
 *                         will be called when the OBEX server receives a get or
 *                         put request
 *
 *
 * @param authentication   specifies whether authentication is required on
 *                         connections to this server, with TRUE indicating that
 *                         authentication is required
 *
 * @param connectOptions   OBEX options for this connection. Can be NULL if no options are being
 *                         specified.
 *
 * @param lowerProtocolList [In/Out] This parameter is a pointer to a list of lower layer protocols
 *                          for which the server is to be registered. The caller must initialize the
 *                          protocol field of each serviceId structure, OBEX will write the lower
 *                          layer service identifier into the the list.  The upper layer will use the
 *                          this information when registering the service record for this server in
 *                          the SDP database. If a requested lower layer protocol is not supported
 *                          the protocol field with be set to OI_OBEX_LOWER_NONE.
 *
 * @param numProtocols      The length of the lowerProtocolList.
 *
 * @param policy            The connection policy to use.  Policy may not be null.
 *
 * @param serverHandle      [Out] Returns a handle for the server instance. This handle is used when
 *                          deregistering the server or when registering secondary targets.
 *
 * @return                 OI_OK if successful or an error status if the target
 *                         could not be registered
 */
OI_STATUS OI_OBEXSRV_RegisterServer(const OI_OBEX_BYTESEQ *target,
                                    const OI_OBEXSRV_CB_LIST *CBList,
                                    OI_OBEXSRV_AUTHENTICATION authentication,
                                    OI_OBEX_CONNECTION_OPTIONS *connectOptions,
                                    OI_OBEX_LOWER_PROTOCOL *lowerProtocolList,
                                    OI_UINT8 numProtocols,
                                    const OI_CONNECT_POLICY *policy,
                                    OI_OBEX_SERVER_HANDLE *serverHandle);

/**
 * This function registers an additional target on an existing OBEX server.
 *
 * @param target            a byte sequence that identifies the OBEX target for
 *                          the service being registered; must not be NULL.
 *
 * @param CBList           pointer to a list of the application functions that
 *                         will be called when the OBEX server receives a get or
 *                         put request
 *
 *
 * @param authentication   specifies whether authentication is required on
 *                         connections to this server, with TRUE indicating that
 *                         authentication is required
 *
 * @param serverHandle     specifies a server handle for an already-registered OBEX server to which
 *                         the secondary target will be attached.
 *
 * @return                 OI_OK if successful or an error status if the target
 *                         could not be registered
 */

OI_STATUS OI_OBEXSRV_RegisterSecondaryTarget(const OI_OBEX_BYTESEQ *target,
                                             const OI_OBEXSRV_CB_LIST *CBList,
                                             OI_OBEXSRV_AUTHENTICATION authentication,
                                             OI_OBEX_SERVER_HANDLE serverHandle);

/**
 * This function deregisters an OBEX server so that it will no longer accept put
 * and/or get requests from OBEX clients for the specified target. This will
 * also deregister any secondary targets associated with this server.
 *
 * To deregister a server that has active connections, terminate the connections
 * using OI_OBEXSRV_ForceDisconnect() first; then deregister the server.
 *
 * @param serverHandle   the handle for the server
 *
 * @return    status code indicating the result of the command to deregister the server:
 *            - OI_OK if the target was deregistered;
 *            - OI_OBEX_SERVICE_UNAVAILABLE if the server handle is invalid
 *            - OI_OBEX_OPERATION_IN_PROGRESS if a client is connected to the
 *              service. To deregister a server that is in use, the application
 *              should call OI_OBEXSRVE_ForceDisconnect() and then call
 *              OI_OBEXSRV_DeregisterServer() again after the disconnect
 *              indication is reported.
 */

OI_STATUS OI_OBEXSRV_DeregisterServer(OI_OBEX_SERVER_HANDLE serverHandle);


/**
 * This function returns TRUE if any client is currently connected to the server
 * associated with the specified server handle. If it returns FALSE, the server
 * is not in use, and deregistration will be successful.
 *
 * @param serverHandle   the handle for the server to deregister.
 *
 * @return                TRUE if the server is busy.
 */
OI_BOOL OI_OBEXSRV_IsServerBusy(OI_OBEX_SERVER_HANDLE serverHandle);


/**
 * Associates a caller defined context with an OBEX server connection. This
 * context can then be retrieved by calling OI_OBEXSRV_GetConnectionContext().
 *
 * @param connectionId   The connection to associate the context with.
 *
 * @param context         A value supplied by the caller.
 *
 * @return                OI_OK if the context was set, OI_STATUS_NOT_FOUND if
 *                        the connection id is not valid.
 */
OI_STATUS OI_OBEXSRV_SetConnectionContext(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                          void *context);


/**
 * Gets a caller defined context associate with an OBEX server connection. This is a value
 * that we previously set by a call to OI_OBEXSRV_SetConnectionContext().
 *
 * @param connectionId    The OBEX server connection to get the context from.
 *
 * @return                A context pointer or NULL if the handle is invalid or
 *                        there is no context associated with this connection.
 */
void* OI_OBEXSRV_GetConnectionContext(OI_OBEXSRV_CONNECTION_HANDLE connectionId);


/**
 * Associates a caller defined context with an OBEX server instance. This
 * context can then be retrieved by calling OI_OBEXSRV_GetServerContext().
 *
 * @param serverHandle    the handle for the server
 *
 * @param context         A value supplied by the caller.
 *
 * @return                OI_OK if the context was set, OI_STATUS_NOT_FOUND if
 *                        the connection id is not valid.
 */
OI_STATUS OI_OBEXSRV_SetServerContext(OI_OBEX_SERVER_HANDLE serverHandle,
                                      void *context);


/**
 * Gets a caller defined context associate with an OBEX server. This is a value
 * that we previously set by a call to OI_OBEXSRV_SetServerContext().
 *
 * @param serverHandle   the handle for the server
 *
 * @return               A context pointer or NULL if the handle is invalid or
 *                       there is no context associated with this connection.
 */
void* OI_OBEXSRV_GetServerContext(OI_OBEX_SERVER_HANDLE serverHandle);


/**
 * @param connectionHandle  The OBEX server connection to get the server handle from.
 *
 * @return    The server handle for this connection or NULL if the connection handle is invalid.
 */
OI_OBEX_SERVER_HANDLE OI_OBEXSRV_GetServerHandle(OI_OBEXSRV_CONNECTION_HANDLE connectionHandle);


/**
 * Returns a count of the number of clients connected to this server.
 *
 * @param serverHandle   the handle for the server
 *
 * @return  The number of connected clients
 */
OI_UINT OI_OBEXSRV_GetNumConnections(OI_OBEX_SERVER_HANDLE serverHandle);


/**
 * Returns a text string corresponding to authentication enum value
 */
const OI_CHAR* OI_OBEXSRV_AuthenticationText(OI_OBEXSRV_AUTHENTICATION authentication);


/**
 * Given an OBEX server connection handle this function returns the L2CAP channel for this
 * connection. In the case of OBEX/RFCOMM this is the L2CAP channel for the underlying RFCOMM
 * session. In the case of OBEX/L2CAP this is the L2CAP channel for the OBEX connection.
 *
 * @param connectionId  The OBEX server connection to get the L2CAP channel for
 * @param cid           Pointer to out parameter for the L2CAP CID
 *
 * @return      - OI_OK if the context was set,
 *              - OI_STATUS_NOT_FOUND if the connection id is not valid.
 *              - OI_STATUS_NOT_CONNECTED if the connection is not up or is disconnecting
 *
 *
 */
OI_STATUS OI_OBEXSRV_GetL2capCID(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                 OI_L2CAP_CID *cid);

/**
 * This function returns the raw header list associated with a server callback.  This function
 * must only be called from within a server callback, otherwise results are unpredictable.
 *
 * Some OBEX commands have optional headers (e.g. realm information in an authentication challenge);
 * this API makes those headers available to applications.
 *
 * @param connectionId  The OBEX server connection

 * @param pRawHeaderList    Pointer where OBEX will store pointers to the raw header list.
 *
 * @return      - OI_OK, pRawHeaderList contains pointer to header list, may be NULL.
 *              - any other status, pRawHeaderList returned is undefined
 */
OI_STATUS OI_OBEXSRV_GetRawHeaderList(OI_OBEXSRV_CONNECTION_HANDLE connectionId,
                                      OI_OBEX_HEADER_LIST          **pRawHeaderList);

/*****************************************************************************/

#ifdef __cplusplus
}
#endif

/**@}*/

#endif /* _OI_OBEXSRV_H */
