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

Copyright (c) 2004 Open Mobile Alliance, Ltd.  All Rights Reserved.

This software is made available under the usage and distribution terms 
covered by the Common Public License 1.0 and by using this software you
are bound by the terms and conditions of the same.

EXCEPT AS EXPRESSLY SET FORTH IN THE COMMON PUBLIC LICENSE,
THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, 
ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
   
Each recipient is solely responsible for determining the 
appropriateness of using and distributing this program and assumes 
all risks associated with its exercise of rights under the Common 
Public License, including but not limited to the risks and 
costs of program errors, compliance with applicable laws, 
damage to or loss of data, programs or equipment, and 
unavailability or interruption of operations.

********************************************************************/
#include "httpdefs.h"
#include <xpt.h>
#include "httpserverports.h"
#include "xptmutex.h"

#ifdef __EPOC_OS__
#include "http_globals_epoc.h"
#endif

typedef struct _http_server_port_node {
    struct          _http_server_port_node *next;
    struct          _http_server_port_node *prev;
    StringBuffer_t  pszPort;
    Socket_t        serverSocket;
    int             inUse;
} HttpServerPortNode_t, *HttpServerPortNodePtr_t;

#ifndef __EPOC_OS__
MutexPtr_t listMutex;
HttpServerPortNodePtr_t firstNode = NULL;
#endif                                   
#ifdef __EPOC_OS__
#define listMutex TheHttpGlobalsEpoc()->listMutex
#define firstNode TheHttpGlobalsEpoc()->firstNode
#endif

void initializeServerPorts() {
    listMutex = newMutex();
}

void uninitializeServerPorts() {
    HttpServerPortNodePtr_t node = firstNode;
    HttpServerPortNodePtr_t nextNode = NULL;
    lockMutex( listMutex );
    // iterate list and close all sockets and free list;
    while (node != NULL) {
        xppFree( node->pszPort );
        tcpCloseConnection( &node->serverSocket );
        nextNode = node->next;
        xppFree( node );
    }
#ifndef __EPOC_OS__
    firstNode = NULL;
#else
	ResetFirstNode();
#endif
    unlockMutex( listMutex );
    freeMutex( listMutex );
}

HttpServerPortNodePtr_t findPort( CString_t   pszPort ) {

    HttpServerPortNodePtr_t node = firstNode;
    while (node != NULL) {
        if (xppStrcmp(pszPort, node->pszPort) == 0) {
            break;
        }
        node = node->next;
    }
    return node;
}

TcpRc_t selectServerSocket( CString_t   pszPort, SocketPtr_t serverSock ) {
    HttpServerPortNodePtr_t node = NULL;
    TcpRc_t rc = TCP_RC_OK;
    lockMutex( listMutex );
    node = findPort( pszPort );
	/* SCTSTK : 18/04/2002 */
    if (node == NULL) {
		if ((rc = tcpOpenConnection( pszPort, serverSock, "s" )) == TCP_RC_OK) {
			node = xppMalloc( sizeof( HttpServerPortNode_t ) );
			xppMemset( node, '\0', sizeof( HttpServerPortNode_t ) );
			node->pszPort = xppMalloc( xppStrlen( pszPort) + 1 );
			xppStrcpy( node->pszPort, pszPort );
			node->serverSocket=*serverSock;
			node->next = firstNode;
			firstNode = node;
		}
    }
	else {
		if (node->inUse) {
			rc = TCP_RC_EADDRINUSE;
		} else {
			*serverSock = node->serverSocket;
			node->inUse = 1;
		}
	}
    unlockMutex( listMutex );
    return rc;
}

void        deselectServerSocket( CString_t   pszPort ) {
    HttpServerPortNodePtr_t node;
    lockMutex( listMutex );
    node = findPort( pszPort );
    if ( node ) {
        /* SCTSTK : 18/04/2002 */
        if ( node == firstNode) {
            firstNode = node->next;
        } else {
            node->prev->next = node->next;
        }
		if ( node->pszPort ) xppFree( node->pszPort );
        tcpCloseConnection( &node->serverSocket );
		xppFree( node );
    }
    unlockMutex( listMutex );

}
