mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.7 KiB
181 lines
5.7 KiB
/*
|
|
* 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/osptrans.h>
|
|
#include "../../dprint.h"
|
|
#include "osptoolkit.h"
|
|
|
|
static OSPTTHREADRETURN ospReportUsageWork(void* usagearg);
|
|
|
|
typedef struct _osp_usage
|
|
{
|
|
OSPTTRANHANDLE ospvTransaction; /* Transaction handle */
|
|
unsigned ospvReleaseCode; /* Release code */
|
|
unsigned ospvDuration; /* Length of call */
|
|
time_t ospvStartTime; /* Call start time */
|
|
time_t ospvEndTime; /* Call end time */
|
|
time_t ospvAlertTime; /* Call alert time */
|
|
time_t ospvConnectTime; /* Call connect time */
|
|
unsigned ospvIsPDDInfoPresent; /* Is PDD Info present */
|
|
unsigned ospvPostDialDelay; /* Post Dial Delay */
|
|
unsigned ospvReleaseSource; /* EP that released the call */
|
|
} osp_usage;
|
|
|
|
/*
|
|
* Get OSP transaction ID from transaction handle
|
|
* param transaction OSP transaction headle
|
|
* return OSP transaction ID
|
|
*/
|
|
unsigned long long ospGetTransactionId(
|
|
OSPTTRANHANDLE transaction)
|
|
{
|
|
OSPTTRANS* context = NULL;
|
|
unsigned long long id = 0;
|
|
int errorcode = OSPC_ERR_NO_ERROR;
|
|
|
|
context = OSPPTransactionGetContext(transaction, &errorcode);
|
|
|
|
if (errorcode == OSPC_ERR_NO_ERROR) {
|
|
id = (unsigned long long)context->TransactionID;
|
|
} else {
|
|
LM_ERR("failed to extract transaction_id from transaction handle %d (%d)\n",
|
|
transaction,
|
|
errorcode);
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
/*
|
|
* Create a thread to report OSP usage
|
|
* param ospvTransaction OSP transaction handle
|
|
* param ospvReleaseCode Call release reason
|
|
* param ospvDurating Call duration
|
|
* param ospvStartTime Call start time
|
|
* param ospvEndTime Call end time
|
|
* param ospvAlertTime Call alert time
|
|
* param ospvConnectTime Call connected time
|
|
* param ospvIsPDDInfoPresent If post dial delay information avaliable
|
|
* param ospvPostDialDelay Post dial delay information
|
|
* param ospvReleaseSource Which side release the call
|
|
*/
|
|
void ospReportUsageWrapper(
|
|
OSPTTRANHANDLE ospvTransaction,
|
|
unsigned ospvReleaseCode,
|
|
unsigned ospvDuration,
|
|
time_t ospvStartTime,
|
|
time_t ospvEndTime,
|
|
time_t ospvAlertTime,
|
|
time_t ospvConnectTime,
|
|
unsigned ospvIsPDDInfoPresent,
|
|
unsigned ospvPostDialDelay,
|
|
unsigned ospvReleaseSource)
|
|
{
|
|
osp_usage* usage;
|
|
OSPTTHREADID threadid;
|
|
OSPTTHRATTR threadattr;
|
|
int errorcode;
|
|
|
|
LM_DBG("schedule usage report for '%llu'\n", ospGetTransactionId(ospvTransaction));
|
|
|
|
usage = (osp_usage*)malloc(sizeof(osp_usage));
|
|
|
|
usage->ospvTransaction = ospvTransaction;
|
|
usage->ospvReleaseCode = ospvReleaseCode;
|
|
usage->ospvDuration = ospvDuration;
|
|
usage->ospvStartTime = ospvStartTime;
|
|
usage->ospvEndTime = ospvEndTime;
|
|
usage->ospvAlertTime = ospvAlertTime;
|
|
usage->ospvConnectTime = ospvConnectTime;
|
|
usage->ospvIsPDDInfoPresent = ospvIsPDDInfoPresent;
|
|
usage->ospvPostDialDelay = ospvPostDialDelay;
|
|
usage->ospvReleaseSource = ospvReleaseSource;
|
|
|
|
OSPM_THRATTR_INIT(threadattr, errorcode);
|
|
|
|
OSPM_SETDETACHED_STATE(threadattr, errorcode);
|
|
|
|
OSPM_CREATE_THREAD(threadid, &threadattr, ospReportUsageWork, usage, errorcode);
|
|
|
|
OSPM_THRATTR_DESTROY(threadattr);
|
|
}
|
|
|
|
/*
|
|
* Report OSP usage thread function
|
|
* param usagearg OSP usage information
|
|
* return
|
|
*/
|
|
static OSPTTHREADRETURN ospReportUsageWork(
|
|
void* usagearg)
|
|
{
|
|
int i;
|
|
const int MAX_RETRIES = 5;
|
|
osp_usage* usage;
|
|
int errorcode;
|
|
|
|
usage = (osp_usage*)usagearg;
|
|
|
|
OSPPTransactionRecordFailure(
|
|
usage->ospvTransaction,
|
|
(enum OSPEFAILREASON)usage->ospvReleaseCode);
|
|
|
|
for (i = 1; i <= MAX_RETRIES; i++) {
|
|
errorcode = OSPPTransactionReportUsage(
|
|
usage->ospvTransaction,
|
|
usage->ospvDuration,
|
|
usage->ospvStartTime,
|
|
usage->ospvEndTime,
|
|
usage->ospvAlertTime,
|
|
usage->ospvConnectTime,
|
|
usage->ospvIsPDDInfoPresent,
|
|
usage->ospvPostDialDelay,
|
|
usage->ospvReleaseSource,
|
|
(unsigned char*)"", 0, 0, 0, 0, NULL, NULL);
|
|
|
|
if (errorcode == OSPC_ERR_NO_ERROR) {
|
|
LM_DBG("reporte usage for '%llu'\n",
|
|
ospGetTransactionId(usage->ospvTransaction));
|
|
break;
|
|
} else {
|
|
LM_ERR("failed to report usage for '%llu' (%d) attempt '%d' of '%d'\n",
|
|
ospGetTransactionId(usage->ospvTransaction),
|
|
errorcode,
|
|
i,
|
|
MAX_RETRIES);
|
|
}
|
|
}
|
|
|
|
OSPPTransactionDelete(usage->ospvTransaction);
|
|
|
|
free(usage);
|
|
|
|
OSPTTHREADRETURN_NULL();
|
|
}
|