osptoolkit.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * ser osp module.
  3. *
  4. * This module enables ser 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 ser, a free SIP server.
  15. *
  16. * ser 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. * For a license to use the ser software under conditions
  22. * other than those described here, or to purchase support for this
  23. * software, please contact iptel.org by e-mail at the following addresses:
  24. * [email protected]
  25. *
  26. * ser is distributed in the hope that it will be useful,
  27. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  28. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  29. * GNU General Public License for more details.
  30. *
  31. * You should have received a copy of the GNU General Public License
  32. * along with this program; if not, write to the Free Software
  33. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  34. */
  35. #include <osp/osptrans.h>
  36. #include "../../dprint.h"
  37. #include "osptoolkit.h"
  38. static OSPTTHREADRETURN ospReportUsageWork(void* usagearg);
  39. typedef struct _osp_usage
  40. {
  41. OSPTTRANHANDLE ospvTransaction; /* Transaction handle */
  42. unsigned ospvReleaseCode; /* Release code */
  43. unsigned ospvDuration; /* Length of call */
  44. time_t ospvStartTime; /* Call start time */
  45. time_t ospvEndTime; /* Call end time */
  46. time_t ospvAlertTime; /* Call alert time */
  47. time_t ospvConnectTime; /* Call connect time */
  48. unsigned ospvIsPDDInfoPresent; /* Is PDD Info present */
  49. unsigned ospvPostDialDelay; /* Post Dial Delay */
  50. unsigned ospvReleaseSource; /* EP that released the call */
  51. } osp_usage;
  52. /*
  53. * Get OSP transaction ID from transaction handle
  54. * param transaction OSP transaction headle
  55. * return OSP transaction ID
  56. */
  57. unsigned long long ospGetTransactionId(
  58. OSPTTRANHANDLE transaction)
  59. {
  60. OSPTTRANS* context = NULL;
  61. unsigned long long id = 0;
  62. int errorcode = OSPC_ERR_NO_ERROR;
  63. LOG(L_DBG, "osp: ospGetTransactionId\n");
  64. context = OSPPTransactionGetContext(transaction, &errorcode);
  65. if (errorcode == OSPC_ERR_NO_ERROR) {
  66. id = (unsigned long long)context->TransactionID;
  67. } else {
  68. LOG(L_ERR,
  69. "osp: ERROR: failed to extract transaction_id from transaction handle %d (%d)\n",
  70. transaction,
  71. errorcode);
  72. }
  73. return id;
  74. }
  75. /*
  76. * Create a thread to report OSP usage
  77. * param ospvTransaction OSP transaction handle
  78. * param ospvReleaseCode Call release reason
  79. * param ospvDurating Call duration
  80. * param ospvStartTime Call start time
  81. * param ospvEndTime Call end time
  82. * param ospvAlertTime Call alert time
  83. * param ospvConnectTime Call connected time
  84. * param ospvIsPDDInfoPresent If post dial delay information avaliable
  85. * param ospvPostDialDelay Post dial delay information
  86. * param ospvReleaseSource Which side release the call
  87. */
  88. void ospReportUsageWrapper(
  89. OSPTTRANHANDLE ospvTransaction,
  90. unsigned ospvReleaseCode,
  91. unsigned ospvDuration,
  92. time_t ospvStartTime,
  93. time_t ospvEndTime,
  94. time_t ospvAlertTime,
  95. time_t ospvConnectTime,
  96. unsigned ospvIsPDDInfoPresent,
  97. unsigned ospvPostDialDelay,
  98. unsigned ospvReleaseSource)
  99. {
  100. osp_usage* usage;
  101. OSPTTHREADID threadid;
  102. OSPTTHRATTR threadattr;
  103. int errorcode;
  104. LOG(L_DBG, "osp: ospReportUsageWrapper\n");
  105. LOG(L_DBG, "osp: schedule usage report for '%llu'\n", ospGetTransactionId(ospvTransaction));
  106. usage = (osp_usage*)malloc(sizeof(osp_usage));
  107. usage->ospvTransaction = ospvTransaction;
  108. usage->ospvReleaseCode = ospvReleaseCode;
  109. usage->ospvDuration = ospvDuration;
  110. usage->ospvStartTime = ospvStartTime;
  111. usage->ospvEndTime = ospvEndTime;
  112. usage->ospvAlertTime = ospvAlertTime;
  113. usage->ospvConnectTime = ospvConnectTime;
  114. usage->ospvIsPDDInfoPresent = ospvIsPDDInfoPresent;
  115. usage->ospvPostDialDelay = ospvPostDialDelay;
  116. usage->ospvReleaseSource = ospvReleaseSource;
  117. OSPM_THRATTR_INIT(threadattr, errorcode);
  118. OSPM_SETDETACHED_STATE(threadattr, errorcode);
  119. OSPM_CREATE_THREAD(threadid, &threadattr, ospReportUsageWork, usage, errorcode);
  120. OSPM_THRATTR_DESTROY(threadattr);
  121. }
  122. /*
  123. * Report OSP usage thread function
  124. * param usagearg OSP usage information
  125. * return
  126. */
  127. static OSPTTHREADRETURN ospReportUsageWork(
  128. void* usagearg)
  129. {
  130. int i;
  131. const int MAX_RETRIES = 5;
  132. osp_usage* usage;
  133. int errorcode;
  134. LOG(L_DBG, "osp: ospReportUsageWork\n");
  135. usage = (osp_usage*)usagearg;
  136. OSPPTransactionRecordFailure(
  137. usage->ospvTransaction,
  138. (enum OSPEFAILREASON)usage->ospvReleaseCode);
  139. for (i = 1; i <= MAX_RETRIES; i++) {
  140. errorcode = OSPPTransactionReportUsage(
  141. usage->ospvTransaction,
  142. usage->ospvDuration,
  143. usage->ospvStartTime,
  144. usage->ospvEndTime,
  145. usage->ospvAlertTime,
  146. usage->ospvConnectTime,
  147. usage->ospvIsPDDInfoPresent,
  148. usage->ospvPostDialDelay,
  149. usage->ospvReleaseSource,
  150. (unsigned char*)"", 0, 0, 0, 0, NULL, NULL);
  151. if (errorcode == OSPC_ERR_NO_ERROR) {
  152. LOG(L_DBG,
  153. "osp: reporte usage for '%llu'\n",
  154. ospGetTransactionId(usage->ospvTransaction));
  155. break;
  156. } else {
  157. LOG(L_ERR,
  158. "osp: ERROR: failed to report usage for '%llu' (%d) attempt '%d' of '%d'\n",
  159. ospGetTransactionId(usage->ospvTransaction),
  160. errorcode,
  161. i,
  162. MAX_RETRIES);
  163. }
  164. }
  165. OSPPTransactionDelete(usage->ospvTransaction);
  166. free(usage);
  167. OSPTTHREADRETURN_NULL();
  168. }