/* Copyright 1998 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Generic (module.h)
 *
 * THIS FILE REQUIRES CUSTOMISATION
 *
 * � Acorn Computers Ltd. 1997
 *
 */

#include <time.h>

typedef enum {
        flags_USER_AGENT_IN_R6 = 1,
        flags_DATA_LENGTH_IN_R5 = 2
} network_protocol_start_swi_r0_flags;

typedef struct {
        int     next_state;             /* State to enter when all data "done" */
        char    *data;                  /* Data itself */
        size_t  length;                 /* Total length of data */
        size_t  done;                   /* Amount written so far, or read so far */
} arbitrary_data;

/* Structure for remembering headers - can be applicable to protocols other than
 * HTTP, hence it is retained here, but the name is not changed in order to remind
 * us that the processor will deal with the first header in a special manner as per
 * the HTTP protocol.
 */
typedef struct http_header http_header;
struct http_header {
        http_header     *next;          /* Link to next member */
        char            *header;        /* Pointer into text member - is the HTTP header tag */
        char            *value;         /* Pointer into text member - is the tag value setting */
        char            text[1];        /* Entire header but ':' and "\r\n" represented by '\0' terminators */
};


typedef struct session {
        struct          session *next;  /* Pointer to next session */
        int             state;          /* The state of this session */
        int             error_state;    /* Used to record the state before an error occurred */
        int             reported_state; /* R0 status returned on last SWI call (used by status SWI) */
        unsigned int    id;             /* Client handle */
        int             sd;             /* Socket descriptor */
        int             server_code;    /* Server response code */
        int             size;           /* expected size of retrieved object - 0 if unknown */
        unsigned int    sent;           /* Amount of data sent to the client in total by this module */
        char            *uri;           /* Specific part of the URI */
        char            *url;           /* Full URI of the document being fetched */
        char            *host;          /* Host name of the host being contacted */
        int             port;           /* Port number of the host being contacted */
        char            *data;          /* Additional client data to be sent to server */
        int             data_len;       /* Size of data pointed to by 'data'.  strlen(data) if not known */
        char            *agent;         /* User-Agent string to be sent - NULL to use this module's own ID */
        int             donehead;       /* Set to non-zero if we have sent our client an HTTP response header */
        int             reused_socket;  /* Set to non-zero when a socket is being re-used on a persistent connection */
        http_header     *headers;       /* List of headers */
        char            *current_header;/* Holds the current header buffer */
        int             hdrptr;         /* Pointer into current_header */
        time_t          last;           /* Last activity timeout */
        arbitrary_data  command;        /* Queued "command" data being sent to remote server */
        arbitrary_data  response;       /* Reception buffers for receiving data from remote server */
        arbitrary_data  client_pump;    /* Data being pumped to our client */
        int             response_code;  /* Holds the response code for the latest response read */

        /* Protocol specific members added here */
        /* End protocol specific members */
} Session;


/* Session control calls - in ses_ctrl.c */
extern Session *find_session(unsigned int);
extern Session *new_session(void);
extern void kill_session(Session *);
extern void ses_kill_all(void);
extern void session_check(void);
extern void session_init(void);

/* Protocol Start SWI handler */
extern _kernel_oserror *generic_start(_kernel_swi_regs *);

/* Protocol Stop SWI handler */
extern _kernel_oserror *generic_stop(_kernel_swi_regs *);

/* Protocol ReadData SWI handler */
extern _kernel_oserror *generic_readdata(_kernel_swi_regs *);

/* Protocol Status SWI handler */
extern _kernel_oserror *generic_status(_kernel_swi_regs *);

/* Wrapper function for realloc - required because RISC OS 3.1
 * SVC mode realloc is broken
 */
extern char *module_realloc(void */*ptr*/, size_t /*size*/);


/* This is a special marker value used to indicate no error, but
 * that a network wait is in progress and that the module should
 * thread out for a while.  Typically this means exit the SWI
 * handler and wait to be called by the client again because we
 * are busy waiting for a network response or a buffer empty.
 */
#define state_BLOCKING  ((_kernel_oserror *)-3)

/* Switches to user mode, does an OS_Byte 0, switches back
 * thus allowing callbacks to fire
 */
extern _kernel_oserror *usermode_donothing(void);