|
@@ -79,8 +79,7 @@ struct acc_enviroment acc_env;
|
|
|
static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps );
|
|
|
|
|
|
|
|
|
-static inline struct hdr_field* get_rpl_to( struct cell *t,
|
|
|
- struct sip_msg *reply)
|
|
|
+static inline struct hdr_field* get_rpl_to( struct cell *t, struct sip_msg *reply)
|
|
|
{
|
|
|
if (reply==FAKED_REPLY || !reply || !reply->to)
|
|
|
return t->uas.request->to;
|
|
@@ -88,13 +87,39 @@ static inline struct hdr_field* get_rpl_to( struct cell *t,
|
|
|
return reply->to;
|
|
|
}
|
|
|
|
|
|
+void env_set_totag(struct cell *t, struct sip_msg *reply)
|
|
|
+{
|
|
|
+ if (reply==FAKED_REPLY || !reply || !reply->to)
|
|
|
+ tmb.t_get_reply_totag(t->uas.request, &acc_env.to_tag);
|
|
|
+}
|
|
|
+
|
|
|
+int env_set_reason(struct sip_msg *reply, str *buff) {
|
|
|
+ int i;
|
|
|
+ char *p;
|
|
|
+ if (reply!=FAKED_REPLY || !buff || !buff->s || buff->len < 20)
|
|
|
+ return 0;
|
|
|
+ if (strncmp(buff->s, "SIP/2.0 ", 8) != 0) {
|
|
|
+ LM_ERR("not a SIP reply\n");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ p = buff->s + 12;
|
|
|
+ for (i=12;i<buff->len;i++) {
|
|
|
+ if (*p == '\r' || *p == '\n') {
|
|
|
+ acc_env.reason.s = buff->s+12;
|
|
|
+ acc_env.reason.len = i-12;
|
|
|
+ LM_DBG("reason[%.*s]\n", acc_env.reason.len, acc_env.reason.s);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ p++;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
static inline void env_set_to(struct hdr_field *to)
|
|
|
{
|
|
|
acc_env.to = to;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
static inline void env_set_text(char *p, int len)
|
|
|
{
|
|
|
acc_env.text.s = p;
|
|
@@ -114,8 +139,10 @@ static inline void env_set_code_status( int code, struct sip_msg *reply)
|
|
|
acc_env.code_s.s =
|
|
|
int2bstr((unsigned long)code, code_buf, &acc_env.code_s.len);
|
|
|
/* reason */
|
|
|
- acc_env.reason.s = error_text(code);
|
|
|
- acc_env.reason.len = strlen(acc_env.reason.s);
|
|
|
+ if (acc_env.reason.len == 0) { /* already extracted in case of locally generated replies */
|
|
|
+ acc_env.reason.s = error_text(code);
|
|
|
+ acc_env.reason.len = strlen(acc_env.reason.s);
|
|
|
+ }
|
|
|
} else {
|
|
|
acc_env.code_s = reply->first_line.u.reply.status;
|
|
|
hf = NULL;
|
|
@@ -493,7 +520,9 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
|
|
|
|
|
|
/* set env variables */
|
|
|
env_set_to( get_rpl_to(t,reply) );
|
|
|
- env_set_code_status( code, reply);
|
|
|
+ env_set_code_status(code, reply);
|
|
|
+ /* for missed calls, we make sure to include the totag if it is locally generated */
|
|
|
+ env_set_totag(t, reply);
|
|
|
|
|
|
/* we report on missed calls when the first
|
|
|
* forwarding attempt fails; we do not wish to
|
|
@@ -512,7 +541,6 @@ static inline void on_missed(struct cell *t, struct sip_msg *req,
|
|
|
acc_db_request( req );
|
|
|
flags_to_reset |= 1 << db_missed_flag;
|
|
|
}
|
|
|
-
|
|
|
/* run extra acc engines */
|
|
|
acc_run_engines(req, 1, &flags_to_reset);
|
|
|
|
|
@@ -691,6 +719,7 @@ static void tmcb_func( struct cell* t, int type, struct tmcb_params *ps )
|
|
|
LM_DBG("acc callback called for t(%p) event type %d, reply code %d\n",
|
|
|
t, type, ps->code);
|
|
|
if (type&TMCB_RESPONSE_OUT) {
|
|
|
+ env_set_reason(ps->rpl, &ps->send_buf);
|
|
|
acc_onreply( t, ps->req, ps->rpl, ps->code);
|
|
|
} else if (type&TMCB_E2EACK_IN) {
|
|
|
acc_onack( t, t->uas.request, ps->req, ps->code);
|