i didn't get any response to this on users list. perhaps the question
fits better to dev list:
what would it take to make avpops module to print config file line
number when error occurs?
now i just get:
Jun 24 14:13:43 host /usr/sbin/sip-proxy[29890]: ERROR: avpops
[avpops_impl.c:1170]: ops_check_avp(): value types don't match
-- juha
Module: sip-router
Branch: tmp/tm_async_reply_support
Commit: 733d8ca38dd6fc4f931cd48cdb0bf8f7634857e7
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=733d8ca…
Author: Richard Good <richard.good(a)smilecoms.com>
Committer: Richard Good <richard.good(a)smilecoms.com>
Date: Thu Jul 4 17:10:16 2013 +0200
modules/tm: Updated documentation to include t_suspend
- API documentation updated to include new methods:
t_suspend_reply, t_continue_reply, t_cancel_suspend_reply
---
modules/tm/doc/api.xml | 122 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/modules/tm/doc/api.xml b/modules/tm/doc/api.xml
index 2a627ab..7aeea5d 100644
--- a/modules/tm/doc/api.xml
+++ b/modules/tm/doc/api.xml
@@ -262,5 +262,127 @@ end of body
</itemizedlist>
<para>Return value: 0 - success, <0 - error.</para>
</section>
+
+ <section id="t_suspend_reply">
+ <title>
+ <function>int t_suspend_reply(struct sip_msg *msg,
+ unsigned int *hash_index, unsigned int *label)</function>
+ </title>
+ <para>
+ For programmatic use only.
+ This function is the equivalent of t_continue, but used to
+ suspend on SIP responses.
+ This function together with t_continue_reply() can be used to
+ implement asynchronous actions on responses: t_suspend() saves
+ the transaction, returns its identifiers, and t_continue() continues the
+ SIP response processing. (The response processing does not continue
+ from the same point in the script, a separate route block defined
+ by the parameter of t_continue_reply() is executed instead. The reply lock
+ is held during the route block execution.)
+ FR timer is ticking while the transaction is suspended, and the
+ transaction's failure route is executed if t_continue() is not
+ called in time.
+ </para>
+ <para>Meaning of the parameters is as follows:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>msg</emphasis> - SIP message pointer.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>hash_index</emphasis> - transaction identifier.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>label</emphasis> - transaction identifier.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>Return value: 0 - success, <0 - error.</para>
+ <para>
+ Usage: Allocate a memory block for storing the transaction identifiers
+ (hash_index and label), and for storing also any variable related to
+ the async query. Before calling t_suspend(), register for the following
+ callbacks, and pass the pointer to the allocated shared memory as
+ a parameter: TMCB_ON_FAILURE, TMCB_DESTROY, and TMCB_E2ECANCEL_IN
+ (in case of INVITE transaction). The async operation can be
+ cancelled, if it is still pending, when TMCB_ON_FAILURE or
+ TMCB_E2ECANCEL_IN is called. TMCB_DESTROY is suitable to free
+ the shared memory allocated for the async and SIP transaction identifiers.
+ Once the async query result is available call t_continue(), see below.
+ The SIP transaction must exist before calling t_suspend(), and the module
+ function calling t_suspend() should return 0 to make sure that the script
+ processing does not continue.
+ </para>
+ </section>
+
+ <section id="t_continue_reply">
+ <title>
+ <function>int t_continue_reply(unsigned int hash_index, unsigned int label,
+ struct action *route, int branch)</function>
+ </title>
+ <para>
+ For programmatic use only.
+ This function is the equivalent of t_continue but used to
+ suspend on SIP responses.
+ This function is the pair of t_suspend_reply(), and is supposed
+ to be called when the asynchronous query result is available.
+ The function executes a route block with the saved SIP message.
+ The calling application passes in the branch of the suspended
+ reply when wanting to continue.
+ </para>
+ <para>Meaning of the parameters is as follows:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>hash_index</emphasis> - transaction identifier.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>label</emphasis> - transaction identifier.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>route</emphasis> - route block to execute.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>branch</emphasis> - reply branch to resume.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>Return value: 0 - success, <0 - error.</para>
+ </section>
+
+ <section id="t_cancel_suspend_reply">
+ <title>
+ <function>int t_cancel_suspend_reply(unsigned int hash_index, unsigned int label, branch)</function>
+ </title>
+ <para>
+ For programmatic use only.
+ This function is the equivalent of t_cancel_suspend but for SIP
+ responses.
+ This function is for revoking t_suspend_reply() from the
+ same process as it was executed before. t_cancel_suspend_reply() can be
+ used when something fails after t_suspend_reply() has already been executed
+ and it turns out that the transcation should not have been
+ suspended. The function cancels the FR timer of the transacation.
+ </para>
+ <para>Meaning of the parameters is as follows:</para>
+ <itemizedlist>
+ <listitem>
+ <para><emphasis>hash_index</emphasis> - transaction identifier.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>label</emphasis> - transaction identifier.
+ </para>
+ </listitem>
+ <listitem>
+ <para><emphasis>branch</emphasis> - reply branch that was suspended.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>Return value: 0 - success, <0 - error.</para>
+ </section>
</section>
</section>
Module: sip-router
Branch: master
Commit: d4cef7f5e49105c65df9651a1ad086b035f8ffdb
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d4cef7f…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Thu Jul 4 11:48:26 2013 +0200
tm: avoid double execution of response-in callbacks
- double execution of response-in callbacks could happen when using tm
pvs inside core reply route, being done in transaction matching
function, which is executed again by tm reply received function
---
modules/tm/t_lookup.c | 55 ++++++++++++++++++++++++++----------------------
1 files changed, 30 insertions(+), 25 deletions(-)
diff --git a/modules/tm/t_lookup.c b/modules/tm/t_lookup.c
index 8c34a81..fbc624b 100644
--- a/modules/tm/t_lookup.c
+++ b/modules/tm/t_lookup.c
@@ -1001,33 +1001,38 @@ int t_reply_matching( struct sip_msg *p_msg , int *p_branch )
REF_UNSAFE( T );
UNLOCK_HASH(hash_index);
DBG("DEBUG: t_reply_matching: reply matched (T=%p)!\n",T);
- /* if this is a 200 for INVITE, we will wish to store to-tags to be
- * able to distinguish retransmissions later and not to call
- * TMCB_RESPONSE_OUT uselessly; we do it only if callbacks are
- * enabled -- except callback customers, nobody cares about
- * retransmissions of multiple 200/INV or ACK/200s
- */
- if (unlikely( is_invite(p_cell) && p_msg->REPLY_STATUS>=200
- && p_msg->REPLY_STATUS<300
- && ((!is_local(p_cell) &&
- has_tran_tmcbs(p_cell,
- TMCB_RESPONSE_OUT|TMCB_RESPONSE_READY
- |TMCB_E2EACK_IN|TMCB_E2EACK_RETR_IN) )
- || (is_local(p_cell)&&has_tran_tmcbs(p_cell, TMCB_LOCAL_COMPLETED))
- )) ) {
- if (parse_headers(p_msg, HDR_TO_F, 0)==-1) {
- LOG(L_ERR, "ERROR: t_reply_matching: to parsing failed\n");
+ if(likely(!(p_msg->msg_flags&FL_TM_RPL_MATCHED))) {
+ /* if this is a 200 for INVITE, we will wish to store to-tags to be
+ * able to distinguish retransmissions later and not to call
+ * TMCB_RESPONSE_OUT uselessly; we do it only if callbacks are
+ * enabled -- except callback customers, nobody cares about
+ * retransmissions of multiple 200/INV or ACK/200s
+ */
+ if (unlikely( is_invite(p_cell) && p_msg->REPLY_STATUS>=200
+ && p_msg->REPLY_STATUS<300
+ && ((!is_local(p_cell) &&
+ has_tran_tmcbs(p_cell,
+ TMCB_RESPONSE_OUT|TMCB_RESPONSE_READY
+ |TMCB_E2EACK_IN|TMCB_E2EACK_RETR_IN) )
+ || (is_local(p_cell)&&has_tran_tmcbs(p_cell, TMCB_LOCAL_COMPLETED))
+ )) ) {
+ if (parse_headers(p_msg, HDR_TO_F, 0)==-1) {
+ LOG(L_ERR, "ERROR: t_reply_matching: to parsing failed\n");
+ }
}
- }
- if (unlikely(has_tran_tmcbs(T, TMCB_RESPONSE_IN |
- TMCB_LOCAL_RESPONSE_IN))){
- if (!is_local(p_cell)) {
- run_trans_callbacks( TMCB_RESPONSE_IN, T, T->uas.request,
- p_msg, p_msg->REPLY_STATUS);
- }else{
- run_trans_callbacks( TMCB_LOCAL_RESPONSE_IN, T, T->uas.request,
- p_msg, p_msg->REPLY_STATUS);
+ if (unlikely(has_tran_tmcbs(T, TMCB_RESPONSE_IN |
+ TMCB_LOCAL_RESPONSE_IN))){
+ if (!is_local(p_cell)) {
+ run_trans_callbacks( TMCB_RESPONSE_IN, T, T->uas.request,
+ p_msg, p_msg->REPLY_STATUS);
+ }else{
+ run_trans_callbacks( TMCB_LOCAL_RESPONSE_IN, T, T->uas.request,
+ p_msg, p_msg->REPLY_STATUS);
+ }
}
+ p_msg->msg_flags |= FL_TM_RPL_MATCHED;
+ } else {
+ DBG("reply in callbacks already done (T=%p)!\n", T);
}
return 1;
} /* for cycle */