osptoolkit.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Kamailio osp module.
  3. *
  4. * This module enables Kamailio to communicate with an Open Settlement
  5. * Protocol (OSP) server. The Open Settlement Protocol is an ETSI
  6. * defined standard for Inter-Domain VoIP pricing, authorization
  7. * and usage exchange. The technical specifications for OSP
  8. * (ETSI TS 101 321 V4.1.1) are available at www.etsi.org.
  9. *
  10. * Uli Abend was the original contributor to this module.
  11. *
  12. * Copyright (C) 2001-2005 Fhg Fokus
  13. *
  14. * This file is part of Kamailio, a free SIP server.
  15. *
  16. * Kamailio is free software; you can redistribute it and/or modify
  17. * it under the terms of the GNU General Public License as published by
  18. * the Free Software Foundation; either version 2 of the License, or
  19. * (at your option) any later version
  20. *
  21. * Kamailio is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU General Public License
  27. * along with this program; if not, write to the Free Software
  28. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  29. */
  30. #include <osp/osptrans.h>
  31. #include "../../dprint.h"
  32. #include "osptoolkit.h"
  33. static OSPTTHREADRETURN ospReportUsageWork(void* usagearg);
  34. typedef struct _osp_usage
  35. {
  36. OSPTTRANHANDLE ospvTransaction; /* Transaction handle */
  37. unsigned ospvReleaseCode; /* Release code */
  38. unsigned ospvDuration; /* Length of call */
  39. time_t ospvStartTime; /* Call start time */
  40. time_t ospvEndTime; /* Call end time */
  41. time_t ospvAlertTime; /* Call alert time */
  42. time_t ospvConnectTime; /* Call connect time */
  43. unsigned ospvIsPDDInfoPresent; /* Is PDD Info present */
  44. unsigned ospvPostDialDelay; /* Post Dial Delay */
  45. unsigned ospvReleaseSource; /* EP that released the call */
  46. } osp_usage;
  47. /*
  48. * Get OSP transaction ID from transaction handle
  49. * param transaction OSP transaction headle
  50. * return OSP transaction ID
  51. */
  52. unsigned long long ospGetTransactionId(
  53. OSPTTRANHANDLE transaction)
  54. {
  55. OSPTTRANS* context = NULL;
  56. unsigned long long id = 0;
  57. int errorcode = OSPC_ERR_NO_ERROR;
  58. context = OSPPTransactionGetContext(transaction, &errorcode);
  59. if (errorcode == OSPC_ERR_NO_ERROR) {
  60. id = (unsigned long long)context->TransactionID;
  61. } else {
  62. LM_ERR("failed to extract transaction_id from transaction handle %d (%d)\n",
  63. transaction,
  64. errorcode);
  65. }
  66. return id;
  67. }
  68. /*
  69. * Create a thread to report OSP usage
  70. * param ospvTransaction OSP transaction handle
  71. * param ospvReleaseCode Call release reason
  72. * param ospvDurating Call duration
  73. * param ospvStartTime Call start time
  74. * param ospvEndTime Call end time
  75. * param ospvAlertTime Call alert time
  76. * param ospvConnectTime Call connected time
  77. * param ospvIsPDDInfoPresent If post dial delay information avaliable
  78. * param ospvPostDialDelay Post dial delay information
  79. * param ospvReleaseSource Which side release the call
  80. */
  81. void ospReportUsageWrapper(
  82. OSPTTRANHANDLE ospvTransaction,
  83. unsigned ospvReleaseCode,
  84. unsigned ospvDuration,
  85. time_t ospvStartTime,
  86. time_t ospvEndTime,
  87. time_t ospvAlertTime,
  88. time_t ospvConnectTime,
  89. unsigned ospvIsPDDInfoPresent,
  90. unsigned ospvPostDialDelay,
  91. unsigned ospvReleaseSource)
  92. {
  93. osp_usage* usage;
  94. OSPTTHREADID threadid;
  95. OSPTTHRATTR threadattr;
  96. int errorcode;
  97. LM_DBG("schedule usage report for '%llu'\n", ospGetTransactionId(ospvTransaction));
  98. usage = (osp_usage*)malloc(sizeof(osp_usage));
  99. usage->ospvTransaction = ospvTransaction;
  100. usage->ospvReleaseCode = ospvReleaseCode;
  101. usage->ospvDuration = ospvDuration;
  102. usage->ospvStartTime = ospvStartTime;
  103. usage->ospvEndTime = ospvEndTime;
  104. usage->ospvAlertTime = ospvAlertTime;
  105. usage->ospvConnectTime = ospvConnectTime;
  106. usage->ospvIsPDDInfoPresent = ospvIsPDDInfoPresent;
  107. usage->ospvPostDialDelay = ospvPostDialDelay;
  108. usage->ospvReleaseSource = ospvReleaseSource;
  109. OSPM_THRATTR_INIT(threadattr, errorcode);
  110. OSPM_SETDETACHED_STATE(threadattr, errorcode);
  111. OSPM_CREATE_THREAD(threadid, &threadattr, ospReportUsageWork, usage, errorcode);
  112. OSPM_THRATTR_DESTROY(threadattr);
  113. }
  114. /*
  115. * Report OSP usage thread function
  116. * param usagearg OSP usage information
  117. * return
  118. */
  119. static OSPTTHREADRETURN ospReportUsageWork(
  120. void* usagearg)
  121. {
  122. int i;
  123. const int MAX_RETRIES = 5;
  124. osp_usage* usage;
  125. int errorcode;
  126. usage = (osp_usage*)usagearg;
  127. OSPPTransactionRecordFailure(
  128. usage->ospvTransaction,
  129. (enum OSPEFAILREASON)usage->ospvReleaseCode);
  130. for (i = 1; i <= MAX_RETRIES; i++) {
  131. errorcode = OSPPTransactionReportUsage(
  132. usage->ospvTransaction,
  133. usage->ospvDuration,
  134. usage->ospvStartTime,
  135. usage->ospvEndTime,
  136. usage->ospvAlertTime,
  137. usage->ospvConnectTime,
  138. usage->ospvIsPDDInfoPresent,
  139. usage->ospvPostDialDelay,
  140. usage->ospvReleaseSource,
  141. (unsigned char*)"", 0, 0, 0, 0, NULL, NULL);
  142. if (errorcode == OSPC_ERR_NO_ERROR) {
  143. LM_DBG("reporte usage for '%llu'\n",
  144. ospGetTransactionId(usage->ospvTransaction));
  145. break;
  146. } else {
  147. LM_ERR("failed to report usage for '%llu' (%d) attempt '%d' of '%d'\n",
  148. ospGetTransactionId(usage->ospvTransaction),
  149. errorcode,
  150. i,
  151. MAX_RETRIES);
  152. }
  153. }
  154. OSPPTransactionDelete(usage->ospvTransaction);
  155. free(usage);
  156. OSPTTHREADRETURN_NULL();
  157. }