/*
 * Kamailio osp module.
 *
 * This module enables Kamailio to communicate with an Open Settlement
 * Protocol (OSP) server.  The Open Settlement Protocol is an ETSI
 * defined standard for Inter-Domain VoIP pricing, authorization
 * and usage exchange.  The technical specifications for OSP
 * (ETSI TS 101 321 V4.1.1) are available at www.etsi.org.
 *
 * Uli Abend was the original contributor to this module.
 *
 * Copyright (C) 2001-2005 Fhg Fokus
 *
 * This file is part of Kamailio, a free SIP server.
 *
 * Kamailio is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version
 *
 * Kamailio 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <osp/osp.h>
#include <osp/osputils.h>
#include "../../core/dprint.h"
#include "provider.h"

extern unsigned int _osp_sp_number;
extern char *_osp_sp_uris[];
extern unsigned long _osp_sp_weights[];
extern unsigned char *_osp_private_key;
extern unsigned char *_osp_local_certificate;
extern unsigned char *_osp_ca_certificate;
extern int _osp_ssl_lifetime;
extern int _osp_persistence;
extern int _osp_retry_delay;
extern int _osp_retry_limit;
extern int _osp_timeout;
extern int _osp_crypto_hw;
extern OSPTPROVHANDLE _osp_provider;

/*
 * Create a new OSP provider object per process
 * return 0 success, others failure
 */
int ospSetupProvider(void)
{
	OSPTPRIVATEKEY privatekey;
	OSPTCERT localcert;
	OSPTCERT cacert;
	OSPTCERT *cacerts[1];
	int result;

	cacerts[0] = &cacert;

	if((result = OSPPInit(_osp_crypto_hw)) != 0) {
		LM_ERR("failed to initialize OSP (%d)\n", result);
	} else if(OSPPUtilLoadPEMPrivateKey(_osp_private_key, &privatekey) != 0) {
		LM_ERR("failed to load private key from '%s'\n", _osp_private_key);
	} else if(OSPPUtilLoadPEMCert(_osp_local_certificate, &localcert) != 0) {
		LM_ERR("failed to load local certificate from '%s'\n",
				_osp_local_certificate);
	} else if(OSPPUtilLoadPEMCert(_osp_ca_certificate, &cacert) != 0) {
		LM_ERR("failed to load CA certificate from '%s'\n",
				_osp_ca_certificate);
	} else {
		result = OSPPProviderNew(_osp_sp_number, (const char **)_osp_sp_uris,
				_osp_sp_weights, "http://localhost:1234", &privatekey,
				&localcert, 1, (const OSPTCERT **)cacerts, 1, _osp_ssl_lifetime,
				_osp_sp_number, _osp_persistence, _osp_retry_delay,
				_osp_retry_limit, _osp_timeout, "", "", &_osp_provider);
		if(result != 0) {
			LM_ERR("failed to create provider (%d)\n", result);
		} else {
			LM_DBG("created new (per process) provider '%d'\n", _osp_provider);
			result = 0;
		}
	}

	/*
     * Free space allocated while loading crypto information from PEM-encoded files.
     * There are some problems to free the memory, do not free them
     */
	if(privatekey.PrivateKeyData != NULL) {
		//free(privatekey.PrivateKeyData);
	}

	if(localcert.CertData != NULL) {
		//free(localcert.CertData);
	}

	if(cacert.CertData != NULL) {
		//free(localcert.CertData);
	}

	return result;
}

/*
 * Erase OSP provider object
 * return 0 success, others failure
 */
int ospDeleteProvider(void)
{
	int result;

	if((result = OSPPProviderDelete(_osp_provider, 0)) != 0) {
		LM_ERR("failed to erase provider '%d' (%d)\n", _osp_provider, result);
	}

	return result;
}
