~alpine/aports

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
1

[alpine-aports] [PATCH] main/kamailio upgrade to 4.4.0

Nathan Angelacos <nangel@alpinelinux.org>
Details
Message ID
<1459512894-6534-1-git-send-email-nangel@alpinelinux.org>
Sender timestamp
1459512894
DKIM signature
missing
Download raw message
Patch: +71 -2825
---
 main/kamailio/0002-mohqueue-v0-12.patch           | 2794 ---------------------
 main/kamailio/0003-kamdbctl-backslash.patch       |   13 +-
 main/kamailio/0004-remove-spurious-execinfo.patch |   30 +
 main/kamailio/APKBUILD                            |   59 +-
 4 files changed, 71 insertions(+), 2825 deletions(-)
 delete mode 100644 main/kamailio/0002-mohqueue-v0-12.patch
 create mode 100644 main/kamailio/0004-remove-spurious-execinfo.patch

diff --git a/main/kamailio/0002-mohqueue-v0-12.patch b/main/kamailio/0002-mohqueue-v0-12.patch
deleted file mode 100644
index 63219c4..0000000
--- a/main/kamailio/0002-mohqueue-v0-12.patch
@@ -1,2794 +0,0 @@
diff --git a/modules/mohqueue/Makefile b/modules/mohqueue/Makefile
index 8351c02..f10bb40 100644
--- a/modules/mohqueue/Makefile
+++ b/modules/mohqueue/Makefile
@@ -1,5 +1,6 @@
+# $Id$
 #
-# mohqueue module makefile
+# msgqueue module makefile
 #
 # 
 # WARNING: do not run this directly, it should be run by the master Makefile
diff --git a/modules/mohqueue/NOTES b/modules/mohqueue/NOTES
index 0741d9f..ef2fbb6 100644
--- a/modules/mohqueue/NOTES
+++ b/modules/mohqueue/NOTES
@@ -1,6 +1,9 @@
 Things to look into:
 
 * RFC3261, section 12.1.1 requires UAS to copy Record-Route
+
 * Check to see if any memory leaks.
+
 * Should probably respond when caller says BYE after queue says BYE.
-* check RAck number
+
+* check RAck number
\ No newline at end of file
diff --git a/modules/mohqueue/mohq.c b/modules/mohqueue/mohq.c
index 711f3fe..bc54aca 100644
--- a/modules/mohqueue/mohq.c
+++ b/modules/mohqueue/mohq.c
@@ -1,6 +1,5 @@
 /*
- *
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -60,9 +59,9 @@ static cmd_export_t mod_cmds [] = {
 };
 
 /* PARAMETERS */
-str db_url = str_init(DEFAULT_DB_URL);
-str db_ctable = str_init("mohqcalls");
-str db_qtable = str_init("mohqueues");
+str db_url = str_init (DEFAULT_DB_URL);
+str db_ctable = str_init ("mohqcalls");
+str db_qtable = str_init ("mohqueues");
 char *mohdir = "";
 int moh_maxcalls = 50;
 
@@ -133,83 +132,87 @@ return 0;
 static int init_cfg (void)
 
 {
-  int error = 0;
-  int bfnd = 0;
-  struct stat psb [1];
--
-  /**********
-  * db_url, db_ctable, db_qtable exist?
-  **********/
--  
-  if (!db_url.s || db_url.len<=0)
+int bfnd = 0;
+int berror = 0;
+struct stat psb [1];
+
+/**********
+* db_url, db_ctable, db_qtable exist?
+**********/
+
+if (!db_url.s || db_url.len <= 0)
   {
-    LM_ERR ("db_url parameter not set!\n");
-    error = 1;
+  LM_ERR ("db_url parameter not set!\n");
+  berror = 1;
   }
--
-  if (!db_ctable.s || db_ctable.len<=0)
+if (!db_ctable.s || db_ctable.len <= 0)
   {
-    LM_ERR ("db_ctable parameter not set!\n");
-    error = 1;
+  LM_ERR ("db_ctable parameter not set!\n");
+  berror = 1;
   }
--
-  if (!db_qtable.s || db_qtable.len<=0)
+if (!db_qtable.s || db_qtable.len <= 0)
   {
-    LM_ERR ("db_qtable parameter not set!\n");
-    error = 1;
-  } 
--
-  /**********
-  * mohdir
-  * o exists?
-  * o directory?
-  **********/
--
-  if (!*mohdir) {
-    LM_ERR ("mohdir parameter not set!\n");
-    error = 1;
-  } else if (strlen(mohdir) > MOHDIRLEN) {
-    LM_ERR ("mohdir too long!");
-    error = 1;
+  LM_ERR ("db_qtable parameter not set!\n");
+  berror = 1;
   }
-  if (moh_maxcalls < 1 || moh_maxcalls > 5000)
+
+/**********
+* mohdir
+* o exists?
+* o directory?
+**********/
+
+if (!*mohdir)
   {
-    LM_ERR ("moh_maxcalls not in range of 1-5000!");
-    error = 1;
+  LM_ERR ("mohdir parameter not set!\n");
+  berror = 1;
   }
-  if (error == 1) {
-	return 0;
+else if (strlen (mohdir) > MOHDIRLEN)
+  {
+  LM_ERR ("mohdir too long!\n");
+  berror = 1;
   }
-  pmod_data->pcfg->db_qtable = db_qtable;
-  pmod_data->pcfg->db_ctable = db_ctable;
-  pmod_data->pcfg->db_url = db_url;
-  pmod_data->pcfg->mohdir = mohdir;
--
-  if (!lstat (mohdir, psb))
+else
   {
+  if (!lstat (mohdir, psb))
+    {
     if ((psb->st_mode & S_IFMT) == S_IFDIR)
       { bfnd = 1; }
-  }
+    }
   if (!bfnd)
-  {
+    {
     LM_ERR ("mohdir is not a directory!\n");
-    return 0;
+    berror = 1;
+    }
   }
 
-  /**********
-  * max calls
-  * o valid count?
-  * o alloc memory
-  **********/
+/**********
+* o max calls valid?
+* o alloc memory
+* o save data
+**********/
 
-   pmod_data->pcall_lst = (call_lst *) shm_malloc (sizeof (call_lst) * moh_maxcalls);
-   if (!pmod_data->pcall_lst) {
-       LM_ERR ("Unable to allocate shared memory");
-       return -1;
+if (moh_maxcalls < 1 || moh_maxcalls > 5000)
+  {
+  LM_ERR ("moh_maxcalls not in range of 1-5000!\n");
+  berror = 1;
   }
-  memset (pmod_data->pcall_lst, 0, sizeof (call_lst) * moh_maxcalls);
-  pmod_data->call_cnt = moh_maxcalls;
-  return -1;
+if (berror)
+  { return 0; }
+pmod_data->pcall_lst =
+  (call_lst *) shm_malloc (sizeof (call_lst) * moh_maxcalls);
+if (!pmod_data->pcall_lst)
+  {
+  LM_ERR ("Unable to allocate shared memory!\n");
+  return 0;
+  }
+pmod_data->pcfg->db_url = db_url;
+pmod_data->pcfg->db_ctable = db_ctable;
+pmod_data->pcfg->db_qtable = db_qtable;
+pmod_data->pcfg->mohdir = mohdir;
+memset (pmod_data->pcall_lst, 0, sizeof (call_lst) * moh_maxcalls);
+pmod_data->call_cnt = moh_maxcalls;
+return -1;
 }
 
 /**********
@@ -232,13 +235,13 @@ static int init_db (void)
 str *pdb_url = &pmod_data->pcfg->db_url;
 if (db_bind_mod (pdb_url, pmod_data->pdb))
   {
-  LM_ERR ("Unable to bind DB API using %s", pdb_url->s);
+  LM_ERR ("Unable to bind DB API using %s!\n", pdb_url->s);
   return 0;
   }
 db_func_t *pdb = pmod_data->pdb;
 if (!DB_CAPABILITY ((*pdb), DB_CAP_ALL))
   {
-  LM_ERR ("Selected database %s lacks required capabilities", pdb_url->s);
+  LM_ERR ("Selected database %s lacks required capabilities!\n", pdb_url->s);
   return 0;
   }
 db1_con_t *pconn = mohq_dbconnect ();
@@ -254,14 +257,14 @@ if (!pconn)
 if (db_check_table_version (pdb, pconn,
   &pmod_data->pcfg->db_ctable, MOHQ_CTABLE_VERSION) < 0)
   {
-  LM_ERR ("%s table in DB %s not at version %d",
+  LM_ERR ("%s table in DB %s not at version %d!\n",
     pmod_data->pcfg->db_ctable.s, pdb_url->s, MOHQ_CTABLE_VERSION);
   goto dberr;
   }
 if (db_check_table_version (pdb, pconn,
   &pmod_data->pcfg->db_qtable, MOHQ_QTABLE_VERSION) < 0)
   {
-  LM_ERR ("%s table in DB %s not at version %d",
+  LM_ERR ("%s table in DB %s not at version %d!\n",
     pmod_data->pcfg->db_qtable.s, pdb_url->s, MOHQ_QTABLE_VERSION);
   goto dberr;
   }
@@ -301,7 +304,7 @@ if (rank == PROC_INIT || rank == PROC_TCP_MAIN || rank == PROC_MAIN)
   { return 0; }
 if (!pmod_data->pdb->init)
   {
-  LM_CRIT ("DB API not loaded!");
+  LM_CRIT ("DB API not loaded!\n");
   return -1;
   }
 return 0;
@@ -355,7 +358,7 @@ int mod_init (void)
 pmod_data = (mod_data *) shm_malloc (sizeof (mod_data));
 if (!pmod_data)
   {
-  LM_ERR ("Unable to allocate shared memory");
+  LM_ERR ("Unable to allocate shared memory!\n");
   return -1;
   }
 memset (pmod_data, 0, sizeof (mod_data));
@@ -371,47 +374,59 @@ if (!init_db ())
 
 if (sl_load_api (pmod_data->psl))
   {
-  LM_ERR ("Unable to load SL module\n");
+  LM_ERR ("Unable to load SL module!\n");
   goto initerr;
   }
 if (load_tm_api (pmod_data->ptm))
   {
-  LM_ERR ("Unable to load TM module\n");
+  LM_ERR ("Unable to load TM module!\n");
   goto initerr;
   }
 if (load_rr_api (pmod_data->prr))
   {
-  LM_ERR ("Unable to load RR module\n");
+  LM_ERR ("Unable to load RR module!\n");
   goto initerr;
   }
 pmod_data->fn_rtp_answer = find_export ("rtpproxy_answer", 0, 0);
 if (!pmod_data->fn_rtp_answer)
   {
-  LM_ERR ("Unable to load rtpproxy_answer\n");
+  LM_ERR ("Unable to load rtpproxy_answer!\n");
   goto initerr;
   }
 pmod_data->fn_rtp_offer = find_export ("rtpproxy_offer", 0, 0);
 if (!pmod_data->fn_rtp_offer)
   {
-  LM_ERR ("Unable to load rtpproxy_offer\n");
+  LM_ERR ("Unable to load rtpproxy_offer!\n");
   goto initerr;
   }
 pmod_data->fn_rtp_stream_c = find_export ("rtpproxy_stream2uac", 2, 0);
 if (!pmod_data->fn_rtp_stream_c)
   {
-  LM_ERR ("Unable to load rtpproxy_stream2uac\n");
+  LM_ERR ("Unable to load rtpproxy_stream2uac!\n");
   goto initerr;
   }
 pmod_data->fn_rtp_stream_s = find_export ("rtpproxy_stream2uas", 2, 0);
 if (!pmod_data->fn_rtp_stream_s)
   {
-  LM_ERR ("Unable to load rtpproxy_stream2uas\n");
+  LM_ERR ("Unable to load rtpproxy_stream2uas!\n");
+  goto initerr;
+  }
+pmod_data->fn_rtp_stop_c = find_export ("rtpproxy_stop_stream2uac", 0, 0);
+if (!pmod_data->fn_rtp_stop_c)
+  {
+  LM_ERR ("Unable to load rtpproxy_stop_stream2uac!\n");
+  goto initerr;
+  }
+pmod_data->fn_rtp_stop_s = find_export ("rtpproxy_stop_stream2uas", 0, 0);
+if (!pmod_data->fn_rtp_stop_s)
+  {
+  LM_ERR ("Unable to load rtpproxy_stop_stream2uas!\n");
   goto initerr;
   }
 pmod_data->fn_rtp_destroy = find_export ("rtpproxy_destroy", 0, 0);
 if (!pmod_data->fn_rtp_destroy)
   {
-  LM_ERR ("Unable to load rtpproxy_destroy\n");
+  LM_ERR ("Unable to load rtpproxy_destroy!\n");
   goto initerr;
   }
 
@@ -438,4 +453,4 @@ if (pmod_data->pcall_lock->plock)
 shm_free (pmod_data);
 pmod_data = NULL;
 return -1;
-}
+}
\ No newline at end of file
diff --git a/modules/mohqueue/mohq.h b/modules/mohqueue/mohq.h
index b23e6a3..207bcba 100644
--- a/modules/mohqueue/mohq.h
+++ b/modules/mohqueue/mohq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -61,31 +61,35 @@ typedef struct
 
 /* call_state values */
 #define CLSTA_ENTER     100
-#define CLSTA_PRACKSTRT 101
-#define CLSTA_PRACKRPLY 102
-#define CLSTA_RINGING   103
+#define CLSTA_TRYING    101
+#define CLSTA_PRACKSTRT 102
+#define CLSTA_PRACKRPLY 103
 #define CLSTA_INVITED   104
 #define CLSTA_CANCEL    105
 #define CLSTA_INQUEUE   200
 #define CLSTA_REFER     301
 #define CLSTA_RFRWAIT   302
+#define CLSTA_BYEOK     304
 #define CLSTA_BYE       305
 
 typedef struct
   {
-  int call_active;
-  char call_id [101];
-  char call_from [URI_LEN + 1];
+  char call_buffer [1024];
+  size_t call_buflen;
+  char *call_id;
+  char *call_from;
   char call_referto [URI_LEN + 1];
-  char call_contact [URI_LEN + 1];
-  char call_tag [101];
-  char call_via [1024];
+  char *call_contact;
+  char *call_tag;
+  char *call_via;
+  char *call_route;
   char call_addr [IP_ADDR_MAX_STR_SIZE + 4];
   int call_state;
   int call_cseq;
   int call_aport;
   mohq_lst *pmohq;
   time_t call_time;
+  time_t refer_time;
   unsigned int call_hash;
   unsigned int call_label;
   sip_msg_t *call_pmsg;
@@ -118,6 +122,8 @@ typedef struct
   cmd_function fn_rtp_offer;
   cmd_function fn_rtp_stream_c;
   cmd_function fn_rtp_stream_s;
+  cmd_function fn_rtp_stop_c;
+  cmd_function fn_rtp_stop_s;
   } mod_data;
 
 /**********
@@ -127,4 +133,4 @@ typedef struct
 extern mod_data *pmod_data;
 extern rtpmap prtpmap [];
 
-#endif /* MOHQ_H */
+#endif /* MOHQ_H */
\ No newline at end of file
diff --git a/modules/mohqueue/mohq_common.h b/modules/mohqueue/mohq_common.h
index 9103323..10f6249 100644
--- a/modules/mohqueue/mohq_common.h
+++ b/modules/mohqueue/mohq_common.h
@@ -1,6 +1,5 @@
 /*
- *
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -52,6 +51,7 @@
 #include "../../parser/contact/parse_contact.h"
 #include "../../parser/parse_expires.h"
 #include "../../parser/parse_from.h"
+#include "../../parser/parse_rr.h"
 #include "../../parser/sdp/sdp.h"
 
 /* convenience macros */
@@ -68,7 +68,7 @@
 
 #define MOHQ_STR_APPEND_L( str1, str1_lim, s2, s2_len ) \
 	if ((str1)->len + (s2_len) >= (str1_lim)) { \
-	    LM_ERR( "Failed to append to str: too long" ); \
+	    LM_ERR( "Failed to append to str: too long!\n" ); \
 	} else { \
 	    MOHQ_STR_APPEND((str1), (s2), (s2_len)); \
 	    (str1_lim) -= (s2_len); \
@@ -83,7 +83,7 @@
 
 #define MOHQ_STR_APPEND_CSTR_L( str1, str1_lim, cstr1 ) \
 	if ((str1)->len + strlen(cstr1) >= (str1_lim)) { \
-	    LM_ERR( "Failed to append to str: too long" ); \
+	    LM_ERR( "Failed to append to str: too long!\n" ); \
 	} else { \
 	    MOHQ_STR_APPEND_CSTR((str1), (cstr1)); \
 	}
@@ -100,4 +100,4 @@
 #define MOHQ_HEADER_EMPTY( hdr1 ) \
 	((hdr1) == NULL || MOHQ_STR_EMPTY( &(hdr1)->body ))
 
-#endif /* MOHQ_COMMON_H */
+#endif /* MOHQ_COMMON_H */
\ No newline at end of file
diff --git a/modules/mohqueue/mohq_db.c b/modules/mohqueue/mohq_db.c
index 64ac90e..56e420f 100644
--- a/modules/mohqueue/mohq_db.c
+++ b/modules/mohqueue/mohq_db.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -214,7 +214,7 @@ pcall->call_time = time (0);
 fill_call_vals (prvals, pcall, CALL_COLCNT);
 if (pdb->insert (pconn, prkeys, prvals, CALL_COLCNT) < 0)
   {
-  LM_WARN ("%sUnable to add new row to %s", pfncname,
+  LM_WARN ("%sUnable to add new row to %s\n", pfncname,
     pmod_data->pcfg->db_ctable.s);
   }
 mohq_dbdisconnect (pconn);
@@ -241,7 +241,7 @@ db_func_t *pdb = pmod_data->pdb;
 pdb->use_table (pconn, &pmod_data->pcfg->db_ctable);
 if (pdb->delete (pconn, 0, 0, 0, 0) < 0)
   {
-  LM_WARN ("%sUnable to delete all rows from %s", pfncname,
+  LM_WARN ("%sUnable to delete all rows from %s\n", pfncname,
     pmod_data->pcfg->db_ctable.s);
   }
 return;
@@ -275,7 +275,7 @@ db_val_t prvals [1];
 set_call_val (prvals, 0, CALLCOL_CALL, pcall->call_id);
 if (pdb->delete (pconn, prkeys, 0, prvals, 1) < 0)
   {
-  LM_WARN ("%sUnable to delete row from %s", pfncname,
+  LM_WARN ("%sUnable to delete row from %s\n", pfncname,
     pmod_data->pcfg->db_ctable.s);
   }
 mohq_dbdisconnect (pconn);
@@ -295,7 +295,7 @@ db1_con_t *mohq_dbconnect (void)
 str *pdb_url = &pmod_data->pcfg->db_url;
 db1_con_t *pconn = pmod_data->pdb->init (pdb_url);
 if (!pconn)
-  { LM_ERR ("Unable to connect to DB %s\n", pdb_url->s); }
+  { LM_ERR ("Unable to connect to DB %s!\n", pdb_url->s); }
 return pconn;
 }
 
@@ -346,7 +346,7 @@ db_val_t puvals [1];
 fill_call_vals (puvals, pcall, CALLCOL_STATE);
 if (pdb->update (pconn, pqkeys, 0, pqvals, pukeys, puvals, 1, 1) < 0)
   {
-  LM_WARN ("%sUnable to update row in %s", pfncname,
+  LM_WARN ("%sUnable to update row in %s\n", pfncname,
     pmod_data->pcfg->db_ctable.s);
   }
 mohq_dbdisconnect (pconn);
@@ -388,7 +388,7 @@ puvals->type = DB1_INT;
 puvals->nul = 0;
 if (pdb->update (pconn, pqkeys, 0, pqvals, pukeys, puvals, 1, 1) < 0)
   {
-  LM_WARN ("%sUnable to update row in %s", pfncname,
+  LM_WARN ("%sUnable to update row in %s\n", pfncname,
     pmod_data->pcfg->db_qtable.s);
   }
 mohq_dbdisconnect (pconn);
@@ -523,21 +523,21 @@ for (nidx = 0; nidx < nrows; nidx++)
       if (strcmp (pqlst [nidx2].mohq_mohdir, pmohdir))
         {
         strcpy (pqlst [nidx2].mohq_mohdir, pmohdir);
-        LM_INFO ("Queue,Field (%s,%.*s): Changed", pqname,
+        LM_INFO ("Queue,Field (%s,%.*s): Changed\n", pqname,
           STR_FMT (&MOHQCSTR_MDIR));
         }
       ptext = (char *)VAL_STRING (prowvals + MOHQCOL_MFILE);
       if (strcmp (pqlst [nidx2].mohq_mohfile, ptext))
         {
         strcpy (pqlst [nidx2].mohq_mohfile, ptext);
-        LM_INFO ("Queue,Field (%s,%.*s): Changed", pqname,
+        LM_INFO ("Queue,Field (%s,%.*s): Changed\n", pqname,
           STR_FMT (&MOHQCSTR_MFILE));
         }
       ptext = (char *)VAL_STRING (prowvals + MOHQCOL_NAME);
       if (strcmp (pqlst [nidx2].mohq_name, ptext))
         {
         strcpy (pqlst [nidx2].mohq_name, ptext);
-        LM_INFO ("Queue,Field (%s,%.*s): Changed", pqname,
+        LM_INFO ("Queue,Field (%s,%.*s): Changed\n", pqname,
           STR_FMT (&MOHQCSTR_NAME));
         }
       int bdebug = VAL_INT (prowvals + MOHQCOL_DEBUG) ? MOHQF_DBG : 0;
@@ -547,7 +547,7 @@ for (nidx = 0; nidx < nrows; nidx++)
           { pqlst [nidx2].mohq_flags |= MOHQF_DBG; }
         else
           { pqlst [nidx2].mohq_flags &= ~MOHQF_DBG; }
-        LM_INFO ("Queue,Field (%s,%.*s): Changed", pqname,
+        LM_INFO ("Queue,Field (%s,%.*s): Changed\n", pqname,
           STR_FMT (&MOHQCSTR_DEBUG));
         }
       bfnd = -1;
@@ -590,7 +590,7 @@ for (nidx = 0; nidx < nrows; nidx++)
       (char *)VAL_STRING (prowvals + MOHQCOL_NAME));
     if (VAL_INT (prowvals + MOHQCOL_DEBUG))
       { pnewlst [nsize].mohq_flags |= MOHQF_DBG; }
-    LM_INFO ("Added new queue (%s)", pnewlst [nsize].mohq_name);
+    LM_INFO ("Added new queue (%s)\n", pnewlst [nsize].mohq_name);
     if (nsize)
       { shm_free (pmod_data->pmohq_lst); }
     pmod_data->pmohq_lst = pnewlst;
@@ -611,7 +611,7 @@ for (nidx = 0; nidx < pmod_data->mohq_cnt; nidx++)
 
   if (pqlst [nidx].mohq_flags & MOHQF_CHK)
     { continue; }
-  LM_INFO ("Removed queue (%s)", pqlst [nidx].mohq_name);
+  LM_INFO ("Removed queue (%s)\n", pqlst [nidx].mohq_name);
   if (nidx != (pmod_data->mohq_cnt - 1))
     {
     memcpy (&pqlst [nidx], &pqlst [pmod_data->mohq_cnt - 1],
@@ -621,4 +621,4 @@ for (nidx = 0; nidx < pmod_data->mohq_cnt; nidx++)
   --nidx;
   }
 return;
-}
+}
\ No newline at end of file
diff --git a/modules/mohqueue/mohq_db.h b/modules/mohqueue/mohq_db.h
index 611d455..c343601 100644
--- a/modules/mohqueue/mohq_db.h
+++ b/modules/mohqueue/mohq_db.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -61,4 +61,4 @@ void update_call_rec (call_lst *);
 void update_debug (mohq_lst *, int);
 void update_mohq_lst (db1_con_t *pconn);
 
-#endif /* MOHQ_DB_H */
+#endif /* MOHQ_DB_H */
\ No newline at end of file
diff --git a/modules/mohqueue/mohq_funcs.c b/modules/mohqueue/mohq_funcs.c
index 1d023e6..86699ae 100644
--- a/modules/mohqueue/mohq_funcs.c
+++ b/modules/mohqueue/mohq_funcs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -32,7 +32,7 @@
 #define ALLOWHDR "Allow: INVITE, ACK, BYE, CANCEL, NOTIFY, PRACK"
 #define CLENHDR "Content-Length"
 #define SIPEOL  "\r\n"
-#define USRAGNT "Kamailio MOH Queue v1.0"
+#define USRAGNT "Kamailio MOH Queue v1.2"
 
 /**********
 * local constants
@@ -46,6 +46,7 @@ str pinvite [1] = {STR_STATIC_INIT ("INVITE")};
 str pmi_nolock [1] = {STR_STATIC_INIT ("Unable to lock queue")};
 str pmi_noqueue [1] = {STR_STATIC_INIT ("No matching queue name found")};
 str prefer [1] = {STR_STATIC_INIT ("REFER")};
+str presp_busy [1] = {STR_STATIC_INIT ("Busy Here")};
 str presp_noaccept [1] = {STR_STATIC_INIT ("Not Acceptable Here")};
 str presp_noallow [1] = {STR_STATIC_INIT ("Method Not Allowed")};
 str presp_nocall [1] = {STR_STATIC_INIT ("Call/Transaction Does Not Exist")};
@@ -55,6 +56,7 @@ str presp_reqterm [1] = {STR_STATIC_INIT ("Request Terminated")};
 str presp_ring [1] = {STR_STATIC_INIT ("Ringing")};
 str psipfrag [1] = {STR_STATIC_INIT ("message/sipfrag")};
 str presp_srverr [1] = {STR_STATIC_INIT ("Server Internal Error")};
+str presp_trying [1] = {STR_STATIC_INIT ("Trying to enter MOH queue")};
 str presp_unsupp [1] = {STR_STATIC_INIT ("Unsupported Media Type")};
 
 rtpmap prtpmap [] =
@@ -86,9 +88,9 @@ str pallowhdr [1] = { STR_STATIC_INIT (ALLOWHDR SIPEOL) };
 char pbyemsg [] =
   {
   "%s"
+  "%s"
   "Max-Forwards: 70" SIPEOL
   "Contact: <%s>" SIPEOL
-  "User-Agent: " USRAGNT SIPEOL
   };
 
 str pextrahdr [1] =
@@ -98,7 +100,6 @@ str pextrahdr [1] =
   "Supported: 100rel" SIPEOL
   "Accept-Language: en" SIPEOL
   "Content-Type: application/sdp" SIPEOL
-  "User-Agent: " USRAGNT SIPEOL
   )
   };
 
@@ -116,10 +117,11 @@ char pinvitesdp [] =
 char prefermsg [] =
   {
   "%s"
+  "%s"
+  "Contact: <%s>" SIPEOL
   "Max-Forwards: 70" SIPEOL
   "Refer-To: <%s>" SIPEOL
-  "Referred-By: <%.*s>" SIPEOL
-  "User-Agent: " USRAGNT SIPEOL
+  "Referred-By: <%s>" SIPEOL
   };
 
 char preinvitemsg [] =
@@ -129,7 +131,6 @@ char preinvitemsg [] =
   "Contact: <%s>" SIPEOL
   ALLOWHDR SIPEOL
   "Supported: 100rel" SIPEOL
-  "User-Agent: " USRAGNT SIPEOL
   "Accept-Language: en" SIPEOL
   "Content-Type: application/sdp" SIPEOL
   };
@@ -151,8 +152,7 @@ char prtpsdp [] =
 **********/
 
 void delete_call (call_lst *);
-void drop_call (sip_msg_t *, call_lst *);
-int find_call (sip_msg_t *, call_lst **);
+void end_RTP (sip_msg_t *, call_lst *);
 dlg_t *form_dialog (call_lst *, struct to_body *);
 int form_rtp_SDP (str *, call_lst *, char *);
 static void invite_cb (struct cell *, int, struct tmcb_params *);
@@ -162,6 +162,7 @@ int send_prov_rsp (sip_msg_t *, call_lst *);
 int send_rtp_answer (sip_msg_t *, call_lst *);
 int search_hdr_ext (struct hdr_field *, str *);
 int start_stream (sip_msg_t *, call_lst *, int);
+int stop_stream (sip_msg_t *, call_lst *, int);
 
 /**********
 * local functions
@@ -173,10 +174,10 @@ int start_stream (sip_msg_t *, call_lst *, int);
 * INPUT:
 *   Arg (1) = SIP message pointer
 *   Arg (2) = call pointer
-* OUTPUT: 0=failed
+* OUTPUT: none
 **********/
 
-int ack_msg (sip_msg_t *pmsg, call_lst *pcall)
+void ack_msg (sip_msg_t *pmsg, call_lst *pcall)
 
 {
 /**********
@@ -199,7 +200,7 @@ if (pcall->call_state != CLSTA_INVITED)
     mohq_debug (pcall->pmohq, "%sACK from refused re-INVITE (%s)!\n",
       pfncname, pcall->call_from);
     }
-  return 1;
+  return;
   }
 
 /**********
@@ -212,7 +213,7 @@ if (ptm->t_lookup_ident (&ptrans, pcall->call_hash, pcall->call_label) < 0)
   {
   LM_ERR ("%sINVITE transaction missing for call (%s)!\n",
     pfncname, pcall->call_from);
-  return 1;
+  return;
   }
 else
   {
@@ -220,7 +221,7 @@ else
     {
     LM_ERR ("%sRelease transaction failed for call (%s)!\n",
       pfncname, pcall->call_from);
-    return 1;
+    return;
     }
   }
 pcall->call_hash = pcall->call_label = 0;
@@ -233,6 +234,47 @@ pcall->call_cseq = 1;
 mohq_debug (pcall->pmohq,
   "%sACK received for call (%s); placed in queue (%s)",
   pfncname, pcall->call_from, pcall->pmohq->mohq_name);
+return;
+}
+
+/**********
+* Add String to Buffer
+*
+* INPUT:
+*   Arg (1) = string pointer
+*   Arg (2) = string length
+*   Arg (3) = pointer to buffer pointer
+*   Arg (4) = pointer to buffer size
+*   Arg (5) = add NUL flag
+* OUTPUT: =0 if insufficent space
+*   bufpointer incremented, size decremented
+**********/
+
+int addstrbfr (char *pstr, size_t nlen, char **pbuf, size_t *nmax, int bnull)
+
+{
+/**********
+* o enough space?
+* o copy string
+* o adjust position/size
+**********/
+
+size_t nsize = nlen;
+if (bnull)
+  { nsize++; }
+if (nsize > *nmax)
+  { return 0; }
+if (nlen)
+  {
+  strncpy (*pbuf, pstr, nlen);
+  *pbuf += nlen;
+  }
+if (bnull)
+  {
+  **pbuf = '\0';
+  (*pbuf)++;
+  }
+*nmax -= nsize;
 return 1;
 }
 
@@ -259,7 +301,7 @@ char *pfncname = "bye_cb: ";
 call_lst *pcall = (call_lst *)*pcbp->param;
 if (ntype == TMCB_ON_FAILURE)
   {
-  LM_ERR ("%sCall (%s) did not respond to BYE\n", pfncname,
+  LM_ERR ("%sCall (%s) did not respond to BYE!\n", pfncname,
     pcall->call_from);
   }
 else
@@ -267,7 +309,7 @@ else
   int nreply = pcbp->code;
   if ((nreply / 100) != 2)
     {
-    LM_ERR ("%sCall (%s) BYE error (%d)\n", pfncname,
+    LM_ERR ("%sCall (%s) BYE error (%d)!\n", pfncname,
       pcall->call_from, nreply);
     }
   else
@@ -286,33 +328,43 @@ return;
 * INPUT:
 *   Arg (1) = SIP message pointer
 *   Arg (2) = call pointer
-* OUTPUT: 0=failed
+* OUTPUT: none
 **********/
 
-int bye_msg (sip_msg_t *pmsg, call_lst *pcall)
+void bye_msg (sip_msg_t *pmsg, call_lst *pcall)
 
 {
 /**********
-* o send OK
-* o teardown call
+* o responded?
+* o teardown RTP
 **********/
 
 char *pfncname = "bye_msg: ";
-if (pmod_data->psl->freply (pmsg, 200, presp_ok) < 0)
+if (pcall->call_state == CLSTA_BYEOK)
+  { return; }
+if (pcall->call_state >= CLSTA_INQUEUE)
   {
-  LM_ERR ("%sUnable to create reply to call (%s)\n", pfncname,
-    pcall->call_from);
-  return 1;
+  pcall->call_state = CLSTA_BYEOK;
+  end_RTP (pmsg, pcall);
   }
-if (pcall->call_state >= CLSTA_INQUEUE)
-  { drop_call (pmsg, pcall); }
 else
   {
   LM_ERR ("%sEnding call (%s) before placed in queue!\n",
     pfncname, pcall->call_from);
-  delete_call (pcall);
   }
-return 1;
+
+/**********
+* send OK and delete from queue
+**********/
+
+if (pmod_data->psl->freply (pmsg, 200, presp_ok) < 0)
+  {
+  LM_ERR ("%sUnable to create reply to call (%s)!\n", pfncname,
+    pcall->call_from);
+  return;
+  }
+delete_call (pcall);
+return;
 }
 
 /**********
@@ -321,14 +373,15 @@ return 1;
 * INPUT:
 *   Arg (1) = SIP message pointer
 *   Arg (2) = call pointer
-* OUTPUT: 0=failed
+* OUTPUT: none
 **********/
 
-int cancel_msg (sip_msg_t *pmsg, call_lst *pcall)
+void cancel_msg (sip_msg_t *pmsg, call_lst *pcall)
 
 {
 /**********
-* still in INVITE dialog?
+* RFC 3261 section 9.2
+* o still in INVITE dialog?
 **********/
 
 char *pfncname = "cancel_msg: ";
@@ -347,7 +400,7 @@ else
   if (pmod_data->psl->freply (pmsg, 481, presp_nocall) < 0)
     { LM_ERR ("%sUnable to create reply!\n", pfncname); }
   }
-return 1;
+return;
 }
 
 /**********
@@ -363,23 +416,14 @@ void close_call (sip_msg_t *pmsg, call_lst *pcall)
 
 {
 /**********
-* o destroy proxy connection
+* o destroy RTP connection
 * o create dialog
 **********/
 
 char *pfncname = "close_call: ";
 int bsent = 0;
 char *phdr = 0;
-if (pmsg != FAKED_REPLY)
-  {
-  mohq_debug (pcall->pmohq, "%sDestroying RTP link for call (%s)",
-    pfncname, pcall->call_from);
-  if (pmod_data->fn_rtp_destroy (pmsg, 0, 0) != 1)
-    {
-    LM_ERR ("%srtpproxy_destroy refused for call (%s)!\n",
-      pfncname, pcall->call_from);
-    }
-  }
+end_RTP (pmsg, pcall);
 struct to_body ptob [2];
 dlg_t *pdlg = form_dialog (pcall, ptob);
 if (!pdlg)
@@ -396,6 +440,7 @@ tm_api_t *ptm = pmod_data->ptm;
 char *pquri = pcall->pmohq->mohq_uri;
 int npos1 = sizeof (pbyemsg) // BYE template
   + strlen (pcall->call_via) // Via
+  + strlen (pcall->call_route) // Route
   + strlen (pquri); // Contact
 phdr = pkg_malloc (npos1);
 if (!phdr)
@@ -405,6 +450,7 @@ if (!phdr)
   }
 sprintf (phdr, pbyemsg,
   pcall->call_via, // Via
+  pcall->call_route, // Route
   pquri); // Contact
 str phdrs [1];
 phdrs->s = phdr;
@@ -424,7 +470,7 @@ if (ptm->t_request_within (puac) < 0)
     pfncname, pcall->call_from);
   goto bye_err;
   }
-mohq_debug (pcall->pmohq, "%sSent BYE request for call (%s)\n",
+mohq_debug (pcall->pmohq, "%sSent BYE request for call (%s)",
   pfncname, pcall->call_from);
 bsent = 1;
 
@@ -447,138 +493,125 @@ return;
 * Create New Call Record
 *
 * INPUT:
-*   Arg (1) = queue index
-*   Arg (2) = SIP message pointer
-* OUTPUT: call index; -1 if unable to create
+*   Arg (1) = SIP message pointer
+*   Arg (2) = call pointer
+*   Arg (3) = call index
+*   Arg (4) = queue index
+* OUTPUT: initializes call record; =0 if failed
 **********/
 
-int create_call (int mohq_idx, sip_msg_t *pmsg)
+int
+create_call (sip_msg_t *pmsg, call_lst *pcall, int ncall_idx, int mohq_idx)
 
 {
 /**********
-* o lock calls
-* o already in use?
-* o find inactive slot
-**********/
--
-char *pfncname = "create_call: ";
-if (!mohq_lock_set (pmod_data->pcall_lock, 1, 2000))
-  {
-  LM_ERR ("%sUnable to lock calls!\n", pfncname);
-  return -1;
-  }
-call_lst *pcall;
-int ncall_idx = find_call (pmsg, &pcall);
-if (pcall)
-  {
-  mohq_lock_release (pmod_data->pcall_lock);
-  LM_ERR ("%sCall already in use (%s)!\n", pfncname, pcall->call_from);
-  return -1;
-  }
-for (ncall_idx = 0; ncall_idx < pmod_data->call_cnt; ncall_idx++)
-  {
-  if (!pmod_data->pcall_lst [ncall_idx].call_active)
-    { break; }
-  }
-if (ncall_idx == pmod_data->call_cnt)
-  {
-  mohq_lock_release (pmod_data->pcall_lock);
-  LM_ERR ("%sNo call slots available!\n", pfncname);
-  return -1;
-  }
--
-/**********
 * add values to new entry
 **********/
 
-pcall = &pmod_data->pcall_lst [ncall_idx];
-pcall->call_active = 1;
+char *pfncname = "create_call: ";
 pcall->pmohq = &pmod_data->pmohq_lst [mohq_idx];
-pcall->call_state = 0;
 str *pstr = &pmsg->callid->body;
-strncpy (pcall->call_id, pstr->s, pstr->len);
-pcall->call_id [pstr->len] = '\0';
+char *pbuf = pcall->call_buffer;
+pcall->call_buflen = sizeof (pcall->call_buffer);
+pcall->call_id = pbuf;
+if (!addstrbfr (pstr->s, pstr->len, &pbuf, &pcall->call_buflen, 1))
+  { return 0; }
 pstr = &pmsg->from->body;
-strncpy (pcall->call_from, pstr->s, pstr->len);
-pcall->call_from [pstr->len] = '\0';
-*pcall->call_tag = '\0';
-if (!pmsg->contact)
-  { *pcall->call_contact = '\0'; }
-else
+pcall->call_from = pbuf;
+if (!addstrbfr (pstr->s, pstr->len, &pbuf, &pcall->call_buflen, 1))
+  { return 0; }
+pcall->call_contact = pbuf;
+if (pmsg->contact)
   {
   pstr = &pmsg->contact->body;
-  strncpy (pcall->call_contact, pstr->s, pstr->len);
-  pcall->call_contact [pstr->len] = '\0';
+  if (!addstrbfr (pstr->s, pstr->len, &pbuf, &pcall->call_buflen, 0))
+    { return 0; }
   }
+if (!addstrbfr (0, 0, &pbuf, &pcall->call_buflen, 1))
+  { return 0; }
 
 /**********
 * extract Via headers
 **********/
 
-hdr_field_t *phdr = pmsg->h_via1;
-if (phdr)
+pcall->call_via = pbuf;
+hdr_field_t *phdr;
+for (phdr = pmsg->h_via1; phdr; phdr = next_sibling_hdr (phdr))
   {
-  int npos1 = 0;
-  while ((phdr = next_sibling_hdr (phdr)))
+  struct via_body *pvia;
+  char *pviabuf;
+  int npos;
+  for (pvia = (struct via_body *)phdr->parsed; pvia; pvia = pvia->next)
     {
-    struct via_body *pvia;
-    char *pviabuf;
-    int bovrflow = 0;
-    int npos2;
-    int nvia_max = sizeof (pcall->call_via);
-    for (pvia = (struct via_body *)phdr->parsed; pvia; pvia = pvia->next)
+    /**********
+    * skip trailing whitespace
+    **********/
+
+    npos = pvia->bsize;
+    pviabuf = pvia->name.s;
+    while (npos)
       {
-      /**********
-      * o skip trailing whitespace
-      * o check if overflow
-      **********/
+      --npos;
+      if (pviabuf [npos] == ' ' || pviabuf [npos] == '\r'
+        || pviabuf [npos] == '\n' || pviabuf [npos] == '\t'
+        || pviabuf [npos] == ',')
+        { continue; }
+      break;
+      }
 
-      npos2 = pvia->bsize;
-      pviabuf = pvia->name.s;
-      while (npos2)
-        {
-        --npos2;
-        if (pviabuf [npos2] == ' ' || pviabuf [npos2] == '\r'
-          || pviabuf [npos2] == '\n' || pviabuf [npos2] == '\t' || pviabuf [npos2] == ',')
-          { continue; }
-        break;
-        }
-      if ((npos2 + npos1 + 7) >= nvia_max)
-        {
-        LM_WARN ("%sVia buffer overflowed!", pfncname);
-        bovrflow = 1;
-        break;
-        }
+    /**********
+    * copy via
+    **********/
 
-      /**********
-      * copy via
-      **********/
+    if (!addstrbfr ("Via: ", 5, &pbuf, &pcall->call_buflen, 0))
+      { return 0; }
+    if (!addstrbfr (pviabuf, npos + 1, &pbuf, &pcall->call_buflen, 0))
+      { return 0; }
+    if (!addstrbfr (SIPEOL, 2, &pbuf, &pcall->call_buflen, 0))
+      { return 0; }
+    }
+  }
+if (!addstrbfr (0, 0, &pbuf, &pcall->call_buflen, 1))
+  { return 0; }
 
-      strcpy (&pcall->call_via [npos1], "Via: ");
-      npos1 += 5;
-      strncpy (&pcall->call_via [npos1], pviabuf, npos2);
-      npos1 += npos2;
-      strcpy (&pcall->call_via [npos1], SIPEOL);
-      npos1 += 2;
-      }
-    if (bovrflow)
-      { break; }
+/**********
+* extract Route headers
+**********/
+
+pcall->call_route = pbuf;
+struct hdr_field *proute;
+for (proute = pmsg->record_route; proute; proute = next_sibling_hdr (proute))
+  {
+  if (parse_rr (proute) < 0)
+    { return 0; }
+  rr_t *prouterr;
+  for (prouterr = proute->parsed; prouterr; prouterr = prouterr->next)
+    {
+    if (!addstrbfr ("Route: ", 7, &pbuf, &pcall->call_buflen, 0))
+      { return 0; }
+    if (!addstrbfr (prouterr->nameaddr.name.s, prouterr->len,
+      &pbuf, &pcall->call_buflen, 0))
+      { return 0; }
+    if (!addstrbfr (SIPEOL, 2, &pbuf, &pcall->call_buflen, 0))
+      { return 0; }
     }
   }
+if (!addstrbfr (0, 0, &pbuf, &pcall->call_buflen, 1))
+  { return 0; }
 
 /**********
-* o release call lock
+* o place tag at the end
 * o update DB
-* o lock MOH queue
 **********/
 
+pcall->call_tag = pbuf;
+if (!addstrbfr (0, 0, &pbuf, &pcall->call_buflen, 1))
+  { return 0; }
 pcall->call_state = CLSTA_ENTER;
-mohq_lock_release (pmod_data->pcall_lock);
 add_call_rec (ncall_idx);
-mohq_lock_set (pmod_data->pmohq_lock, 0, 0);
 mohq_debug (pcall->pmohq, "%sAdded call (%s) to queue (%s)",
   pfncname, pcall->call_from, pcall->pmohq->mohq_name);
-return ncall_idx;
+return 1;
 }
 
 /**********
@@ -603,15 +636,15 @@ if (pcall->call_hash || pcall->call_label)
   {
   if (ptm->t_lookup_ident (&ptrans, pcall->call_hash, pcall->call_label) < 0)
     {
-    LM_ERR ("%sLookup transaction failed for call (%s)!\n", pfncname,
-      pcall->call_from);
+    LM_ERR ("%sLookup transaction failed for call (%s) from queue (%s)!\n",
+      pfncname, pcall->call_from, pcall->pmohq->mohq_name);
     }
   else
     {
     if (ptm->t_release (pcall->call_pmsg) < 0)
       {
-      LM_ERR ("%sRelease transaction failed for call (%s)!\n",
-        pfncname, pcall->call_from);
+      LM_ERR ("%sRelease transaction failed for call (%s) from queue (%s)!\n",
+        pfncname, pcall->call_from, pcall->pmohq->mohq_name);
       }
     }
   pcall->call_hash = pcall->call_label = 0;
@@ -620,14 +653,21 @@ if (pcall->call_hash || pcall->call_label)
 /**********
 * o update DB
 * o inactivate slot
-* o release MOH queue
 **********/
 
-mohq_debug (pcall->pmohq, "delete_call: Deleting call (%s) from queue (%s)",
-  pcall->call_from, pcall->pmohq->mohq_name);
-delete_call_rec (pcall);
-pcall->call_active = 0;
-mohq_lock_release (pmod_data->pmohq_lock);
+if (!mohq_lock_set (pmod_data->pcall_lock, 1, 5000))
+  {
+  LM_ERR ("%sUnable to set call lock for call (%s) from queue (%s)!\n",
+    pfncname, pcall->call_from, pcall->pmohq->mohq_name);
+  }
+else
+  {
+  mohq_debug (pcall->pmohq, "%sDeleting call (%s) from queue (%s)",
+    pfncname, pcall->call_from, pcall->pmohq->mohq_name);
+  delete_call_rec (pcall);
+  mohq_lock_release (pmod_data->pcall_lock);
+  }
+pcall->call_state = 0;
 return;
 }
 
@@ -663,7 +703,7 @@ if (ptm->t_newtran (pmsg) < 0)
   }
 if (!add_lump_rpl2 (pmsg, pallowhdr->s, pallowhdr->len, LUMP_RPL_HDR))
   { LM_ERR ("%sUnable to add Allow header!\n", pfncname); }
-LM_ERR ("%sRefused %.*s for call (%s)!", pfncname,
+LM_ERR ("%sRefused %.*s for call (%s)!\n", pfncname,
   STR_FMT (&REQ_LINE (pmsg).method), pcall->call_from);
 if (ptm->t_reply (pmsg, 405, presp_noallow->s) < 0)
   {
@@ -674,7 +714,7 @@ return;
 }
 
 /**********
-* Drop the Call
+* End RTP
 *
 * INPUT:
 *   Arg (1) = SIP message pointer
@@ -682,16 +722,15 @@ return;
 * OUTPUT: none
 **********/
 
-void drop_call (sip_msg_t *pmsg, call_lst *pcall)
+void end_RTP (sip_msg_t *pmsg, call_lst *pcall)
 
 {
 /**********
-* o destroy proxy connection
-* o delete call
+* destroy RTP connection
 **********/
 
-char *pfncname = "drop_call: ";
-if (pmsg != FAKED_REPLY)
+char *pfncname = "end_RTP: ";
+if ((pmsg != FAKED_REPLY) && (pcall->call_state != CLSTA_ENTER))
   {
   mohq_debug (pcall->pmohq, "%sDestroying RTP link for call (%s)",
     pfncname, pcall->call_from);
@@ -701,7 +740,6 @@ if (pmsg != FAKED_REPLY)
       pfncname, pcall->call_from);
     }
   }
-delete_call (pcall);
 return;
 }
 
@@ -710,62 +748,37 @@ return;
 *
 * INPUT:
 *   Arg (1) = SIP message pointer
-*   Arg (2) = pointer to call pointer
-* OUTPUT: queue index; -1 if unable to find
+*   Arg (2) = queue index
+* OUTPUT: call pointer; =0 if unable to find/create
 **********/
 
-int find_call (sip_msg_t *pmsg, call_lst **ppcall)
+call_lst *find_call (sip_msg_t *pmsg, int mohq_idx)
 
 {
 /**********
-* o find current RURI
-* o strip off parms or headers
-* o search MOH queue
-**********/
--
-str *pruri =
-  pmsg->new_uri.s ? &pmsg->new_uri : &pmsg->first_line.u.request.uri;
-int nidx;
-str pstr [1];
-pstr->s = pruri->s;
-pstr->len = pruri->len;
-for (nidx = 0; nidx < pruri->len; nidx++)
-  {
-  if (pstr->s [nidx] == ';' || pstr->s [nidx] == '?')
-    {
-    pstr->len = nidx;
-    break;
-    }
-  }
-mohq_lst *pqlst = pmod_data->pmohq_lst;
-int nqidx;
-for (nqidx = 0; nqidx < pmod_data->mohq_cnt; nqidx++)
-  {
-  str pmohstr [1];
-  pmohstr->s = pqlst [nqidx].mohq_uri;
-  pmohstr->len = strlen (pmohstr->s);
-  if (STR_EQ (*pmohstr, *pstr))
-    { break; }
-  }
-*ppcall = 0;
-if (nqidx == pmod_data->mohq_cnt)
-  { return -1;}
--
-/**********
 * o get to tag
 * o get callID
-* o ignore to tag if CANCEL on first INVITE
-* o search call queue
+* o search calls
 **********/
 
+char *pfncname = "find_call: ";
 str *ptotag = &(get_to (pmsg)->tag_value);
 if (!ptotag->len)
   { ptotag = 0; }
 if (!pmsg->callid)
-  { return -1; }
+  {
+  LM_ERR ("%sNo call ID!\n", pfncname);
+  return 0;
+  }
 str *pcallid = &pmsg->callid->body;
 if (!pcallid)
-  { return -1; }
+  {
+  LM_ERR ("%sNo call ID!\n", pfncname);
+  return 0;
+  }
+int nopen = -1;
+int nidx;
+call_lst *pcall;
 for (nidx = 0; nidx < pmod_data->call_cnt; nidx++)
   {
   /**********
@@ -773,21 +786,25 @@ for (nidx = 0; nidx < pmod_data->call_cnt; nidx++)
   * o call timed out on ACK?
   * o callID matches?
   * o to tag matches?
-  * o return call pointer
   **********/
 
-  call_lst *pcall = &pmod_data->pcall_lst [nidx];
-  if (!pcall->call_active)
-    { continue; }
+  pcall = &pmod_data->pcall_lst [nidx];
+  if (!pcall->call_state)
+    {
+    nopen = nidx;
+    continue;
+    }
+#if 0 /* ??? need to handle */
   if (pcall->call_time && (pcall->call_state < CLSTA_INQUEUE))
     {
     if ((pcall->call_time + 32) < time (0))
       {
-      LM_ERR ("find_call: No ACK response for call (%s)\n", pcall->call_from);
+      LM_ERR ("%sNo ACK response for call (%s)!\n", pfncname, pcall->call_from);
       delete_call (pcall);
       continue;
       }
     }
+#endif /* ??? */
   str tmpstr [1];
   tmpstr->s = pcall->call_id;
   tmpstr->len = strlen (tmpstr->s);
@@ -800,31 +817,96 @@ for (nidx = 0; nidx < pmod_data->call_cnt; nidx++)
     if (!STR_EQ (*tmpstr, *ptotag))
       { continue; }
     }
-  *ppcall = pcall;
-  return nqidx;
+  else
+    {
+    /**********
+    * match not allowed for INVITE
+    **********/
+
+    if (pmsg->REQ_METHOD == METHOD_INVITE)
+      { return 0; }
+    }
+  return pcall;
   }
 
 /**********
-* first INVITE?
+* o first INVITE?
+* o create a new call record
 **********/
 
-if (pmsg->REQ_METHOD == METHOD_INVITE)
+if (pmsg->REQ_METHOD != METHOD_INVITE)
   { return 0; }
-return -1;
+if (ptotag)
+  { return 0; }
+if (nopen < 0)
+  {
+  LM_ERR ("%sNo call slots available!\n", pfncname);
+  return 0;
+  }
+pcall = &pmod_data->pcall_lst [nopen];
+if (!create_call (pmsg, pcall, nopen, mohq_idx))
+  { return 0; }
+return pcall;
 }
 
 /**********
 * Find Queue
 *
 * INPUT:
+*   Arg (1) = SIP message pointer
+* OUTPUT: queue index; -1 if unable to find
+**********/
+
+int find_queue (sip_msg_t *pmsg)
+
+{
+/**********
+* o find current RURI
+* o strip off parms or headers
+* o search queues
+**********/
+
+str *pruri =
+  pmsg->new_uri.s ? &pmsg->new_uri : &pmsg->first_line.u.request.uri;
+int nidx;
+str pstr [1];
+pstr->s = pruri->s;
+pstr->len = pruri->len;
+for (nidx = 0; nidx < pruri->len; nidx++)
+  {
+  if (pstr->s [nidx] == ';' || pstr->s [nidx] == '?')
+    {
+    pstr->len = nidx;
+    break;
+    }
+  }
+mohq_lst *pqlst = pmod_data->pmohq_lst;
+int nqidx;
+for (nqidx = 0; nqidx < pmod_data->mohq_cnt; nqidx++)
+  {
+  str pmohstr [1];
+  pmohstr->s = pqlst [nqidx].mohq_uri;
+  pmohstr->len = strlen (pmohstr->s);
+  if (STR_EQ (*pmohstr, *pstr))
+    { break; }
+  }
+if (nqidx == pmod_data->mohq_cnt)
+  { return -1;}
+return nqidx;
+}
+
+/**********
+* Find Queue Name
+*
+* INPUT:
 *   Arg (1) = queue name str pointer
 * OUTPUT: queue index; -1 if unable to find
 **********/
 
-int find_queue (str *pqname)
+int find_qname (str *pqname)
 
 {
-char *pfncname = "find_queue: ";
+char *pfncname = "find_qname: ";
 int nidx;
 str tmpstr;
 if (!mohq_lock_set (pmod_data->pmohq_lock, 0, 500))
@@ -869,7 +951,7 @@ parse_to (pvalue->s, &pvalue->s [pvalue->len + 1], pref);
 if (pref->error != PARSE_OK)
   {
   // should never happen
-  LM_ERR ("%sInvalid Referred-By URI (%.*s)!", pfncname, STR_FMT (pvalue));
+  LM_ERR ("%sInvalid Referred-By URI (%.*s)!\n", pfncname, STR_FMT (pvalue));
   return -1;
   }
 if (pref->param_lst)
@@ -884,7 +966,7 @@ str tmpstr;
 struct to_body pfrom [1];
 for (nidx = 0; nidx < pmod_data->call_cnt; nidx++)
   {
-  if (!pmod_data->pcall_lst [nidx].call_active)
+  if (!pmod_data->pcall_lst [nidx].call_state)
     { continue; }
   tmpstr.s = pmod_data->pcall_lst [nidx].call_from;
   tmpstr.len = strlen (tmpstr.s);
@@ -892,7 +974,7 @@ for (nidx = 0; nidx < pmod_data->call_cnt; nidx++)
   if (pfrom->error != PARSE_OK)
     {
     // should never happen
-    LM_ERR ("%sInvalid From URI (%.*s)!", pfncname, STR_FMT (&tmpstr));
+    LM_ERR ("%sInvalid From URI (%.*s)!\n", pfncname, STR_FMT (&tmpstr));
     continue;
     }
   if (pfrom->param_lst)
@@ -908,55 +990,65 @@ return -1;
 *
 * INPUT:
 *   Arg (1) = SIP message pointer
-*   Arg (2) = queue index
-* OUTPUT: 0=failed
+*   Arg (2) = call pointer
+* OUTPUT: none
 **********/
 
-int first_invite_msg (sip_msg_t *pmsg, int mohq_idx)
+void first_invite_msg (sip_msg_t *pmsg, call_lst *pcall)
 
 {
-/**********
-* create call record
-**********/
--
 char *pfncname = "first_invite_msg: ";
-int ncall_idx = create_call (mohq_idx, pmsg);
-if (ncall_idx == -1)
-  { return 0; }
-call_lst *pcall = &pmod_data->pcall_lst [ncall_idx];
 
 /**********
 * o SDP exists?
 * o accepts REFER?
-* o send rtpproxy offer
+* o send RTP offer
 **********/
 
 if (!(pmsg->msg_flags & FL_SDP_BODY))
   {
   if (parse_sdp (pmsg))
     {
-    LM_ERR ("%sINVITE lacks SDP (%s)!", pfncname, pcall->call_from);
+    if (pmod_data->psl->freply (pmsg, 488, presp_noaccept) < 0)
+      {
+      LM_ERR ("%sUnable to create reply!\n", pfncname);
+      return;
+      }
+    LM_ERR ("%sINVITE lacks SDP (%s) from queue (%s)!\n",
+      pfncname, pcall->call_from, pcall->pmohq->mohq_name);
     delete_call (pcall);
-    return 0;
+    return;
     }
   }
 if (pmsg->allow)
   {
   if (!search_hdr_ext (pmsg->allow, prefer))
     {
-    LM_ERR ("%sMissing REFER support (%s)!", pfncname, pcall->call_from);
+    if (pmod_data->psl->freply (pmsg, 488, presp_noaccept) < 0)
+      {
+      LM_ERR ("%sUnable to create reply!\n", pfncname);
+      return;
+      }
+    LM_ERR ("%sMissing REFER support (%s) from queue (%s)!\n",
+      pfncname, pcall->call_from, pcall->pmohq->mohq_name);
     delete_call (pcall);
-    return 0;
+    return;
     }
   }
-mohq_debug (pcall->pmohq, "%sMaking offer for RTP link for call (%s)",
-  pfncname, pcall->call_from);
+mohq_debug (pcall->pmohq,
+  "%sMaking offer for RTP link for call (%s) from queue (%s)",
+  pfncname, pcall->call_from, pcall->pmohq->mohq_name);
 if (pmod_data->fn_rtp_offer (pmsg, 0, 0) != 1)
   {
-  LM_ERR ("%srtpproxy_offer refused for call (%s)!",
-    pfncname, pcall->call_from);
+  if (pmod_data->psl->freply (pmsg, 486, presp_busy) < 0)
+    {
+    LM_ERR ("%sUnable to create reply!\n", pfncname);
+    return;
+    }
+  LM_ERR ("%srtpproxy_offer refused for call (%s)!\n",
+      pfncname, pcall->call_from);
   delete_call (pcall);
-  return 0;
+  return;
   }
 
 /**********
@@ -969,10 +1061,11 @@ if (pmod_data->fn_rtp_offer (pmsg, 0, 0) != 1)
 tm_api_t *ptm = pmod_data->ptm;
 if (ptm->t_newtran (pmsg) < 0)
   {
-  LM_ERR ("%sUnable to create new transaction for call (%s)!",
+  LM_ERR ("%sUnable to create new transaction for call (%s)!\n",
     pfncname, pcall->call_from);
+  end_RTP (pmsg, pcall);
   delete_call (pcall);
-  return 0;
+  return;
   }
 struct cell *ptrans = ptm->t_gett ();
 pcall->call_hash = ptrans->hash_index;
@@ -980,26 +1073,50 @@ pcall->call_label = ptrans->label;
 str ptotag [1];
 if (ptm->t_get_reply_totag (pmsg, ptotag) != 1)
   {
-  LM_ERR ("%sUnable to create totag for call (%s)!",
+  LM_ERR ("%sUnable to create totag for call (%s)!\n",
     pfncname, pcall->call_from);
   if (ptm->t_reply (pmsg, 500, presp_srverr->s) < 0)
-    { LM_ERR ("%sUnable to reply to INVITE!", pfncname); }
+    { LM_ERR ("%sUnable to reply to INVITE!\n", pfncname); }
+  end_RTP (pmsg, pcall);
   delete_call (pcall);
-  return 1;
+  return;
+  }
+char *pbuf = pcall->call_tag;
+if (!addstrbfr (ptotag->s, ptotag->len, &pbuf, &pcall->call_buflen, 1))
+  {
+  LM_ERR ("%sInsufficient buffer space for call (%s)!\n",
+    pfncname, pcall->call_from);
+  if (ptm->t_reply (pmsg, 500, presp_srverr->s) < 0)
+    { LM_ERR ("%sUnable to reply to INVITE!\n", pfncname); }
+  end_RTP (pmsg, pcall);
+  delete_call (pcall);
+  return;
   }
-strncpy (pcall->call_tag, ptotag->s, ptotag->len);
-pcall->call_tag [ptotag->len] = '\0';
 pcall->call_cseq = 1;
 if (ptm->register_tmcb (pmsg, 0, TMCB_DESTROY | TMCB_ON_FAILURE,
   invite_cb, pcall, 0) < 0)
   {
-  LM_ERR ("%sUnable to set callback for call (%s)!",
+  LM_ERR ("%sUnable to set callback for call (%s)!\n",
     pfncname, pcall->call_from);
   if (ptm->t_reply (pmsg, 500, presp_srverr->s) < 0)
-    { LM_ERR ("%sUnable to reply to INVITE!", pfncname); }
+    { LM_ERR ("%sUnable to reply to INVITE!\n", pfncname); }
+  end_RTP (pmsg, pcall);
   delete_call (pcall);
-  return 1;
+  return;
+  }
+
+/**********
+* reply with trying
+**********/
+
+if (ptm->t_reply (pmsg, 100, presp_trying->s) < 0)
+  {
+  LM_ERR ("%sUnable to create reply!\n", pfncname);
+  end_RTP (pmsg, pcall);
+  delete_call (pcall);
+  return;
   }
+pcall->call_state = CLSTA_TRYING;
 
 /**********
 * o add contact to reply
@@ -1009,19 +1126,20 @@ if (ptm->register_tmcb (pmsg, 0, TMCB_DESTROY | TMCB_ON_FAILURE,
 
 str pcontact [1];
 char *pcontacthdr = "Contact: <%s>" SIPEOL;
-pcontact->s = pkg_malloc (strlen (pmod_data->pmohq_lst [mohq_idx].mohq_uri)
-  + strlen (pcontacthdr));
+pcontact->s
+  = pkg_malloc (strlen (pcall->pmohq->mohq_uri) + strlen (pcontacthdr));
 if (!pcontact->s)
   {
-  LM_ERR ("%sNo more memory!", pfncname);
+  LM_ERR ("%sNo more memory!\n", pfncname);
+  end_RTP (pmsg, pcall);
   delete_call (pcall);
-  return 1;
+  return;
   }
-sprintf (pcontact->s, pcontacthdr, pmod_data->pmohq_lst [mohq_idx].mohq_uri);
+sprintf (pcontact->s, pcontacthdr, pcall->pmohq->mohq_uri);
 pcontact->len = strlen (pcontact->s);
 if (!add_lump_rpl2 (pmsg, pcontact->s, pcontact->len, LUMP_RPL_HDR))
   {
-  LM_ERR ("%sUnable to add contact (%s) to call (%s)!",
+  LM_ERR ("%sUnable to add contact (%s) to call (%s)!\n",
     pfncname, pcontact->s, pcall->call_from);
   }
 pkg_free (pcontact->s);
@@ -1030,42 +1148,30 @@ if (search_hdr_ext (pmsg->require, p100rel))
   {
   if (!send_prov_rsp (pmsg, pcall))
     {
+    end_RTP (pmsg, pcall);
     delete_call (pcall);
-    return 1;
+    return;
     }
-  }
-else
-  {
-  if (ptm->t_reply (pmsg, 180, presp_ring->s) < 0)
-    {
-    LM_ERR ("%sUnable to reply to INVITE!", pfncname);
-    return 1;
-    }
-  else
+  if (pcall->call_state == CLSTA_CANCEL)
     {
-    pcall->call_state = CLSTA_RINGING;
-    mohq_debug (pcall->pmohq, "%sSent RINGING for call (%s)",
-      pfncname, pcall->call_from);
+    end_RTP (pmsg, pcall);
+    delete_call (pcall);
+    return;
     }
   }
 
 /**********
-* o call cancelled?
-* o accept call with RTP
+* accept call with RTP
 **********/
 
-if (pcall->call_state == CLSTA_CANCEL)
-  {
-  delete_call (pcall);
-  return 1;
-  }
 if (!send_rtp_answer (pmsg, pcall))
   {
   if (pmod_data->psl->freply (pmsg, 500, presp_srverr) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+  end_RTP (pmsg, pcall);
   delete_call (pcall);
   }
-return 1;
+return;
 }
 
 /**********
@@ -1085,6 +1191,9 @@ dlg_t *form_dialog (call_lst *pcall, struct to_body *pto_body)
 **********/
 
 char *pfncname = "form_dialog: ";
+str pdsturi [1], ptarget [1];
+int index;
+name_addr_t pname [1];
 struct to_body *ptob = &pto_body [0];
 struct to_body *pcontact = &pto_body [1];
 parse_to (pcall->call_from,
@@ -1092,12 +1201,49 @@ parse_to (pcall->call_from,
 if (ptob->error != PARSE_OK)
   {
   // should never happen
-  LM_ERR ("%sInvalid from URI (%s)!", pfncname, pcall->call_from);
+  LM_ERR ("%sInvalid from URI (%s)!\n", pfncname, pcall->call_from);
   return 0;
   }
 if (ptob->param_lst)
   { free_to_params (ptob); }
-str ptarget [1];
+
+/**********
+* form dest URI from record route
+**********/
+
+if (!*pcall->call_route)
+  { pdsturi->s = 0; }
+else
+  {
+  /**********
+  * o find first route URI
+  * o strip off parameter
+  **********/
+
+  pdsturi->s = pcall->call_route;
+  pdsturi->len = strlen (pcall->call_route);
+  if (parse_nameaddr (pdsturi, pname) < 0)
+    {
+    // should never happen
+    LM_ERR ("%sUnable to parse route (%s)!\n", pfncname, pcall->call_from);
+    return 0;
+    }
+  pdsturi->s = pname->uri.s;
+  pdsturi->len = pname->uri.len;
+  for (index = 1; index < pdsturi->len; index++)
+    {
+    if (pdsturi->s [index] == ';')
+      {
+      pdsturi->len = index;
+      break;
+      }
+    }
+  }
+
+/**********
+* form target URI
+**********/
+
 if (!*pcall->call_contact)
   {
   ptarget->s = ptob->uri.s;
@@ -1110,7 +1256,7 @@ else
   if (pcontact->error != PARSE_OK)
     {
     // should never happen
-    LM_ERR ("%sInvalid contact (%s) for call (%s)!", pfncname,
+    LM_ERR ("%sInvalid contact (%s) for call (%s)!\n", pfncname,
       pcall->call_contact, pcall->call_from);
     return 0;
     }
@@ -1127,7 +1273,7 @@ else
 dlg_t *pdlg = (dlg_t *)pkg_malloc (sizeof (dlg_t));
 if (!pdlg)
   {
-  LM_ERR ("%sNo more memory!", pfncname);
+  LM_ERR ("%sNo more memory!\n", pfncname);
   return 0;
   }
 memset (pdlg, 0, sizeof (dlg_t));
@@ -1145,6 +1291,11 @@ pdlg->loc_uri.s = pcall->pmohq->mohq_uri;
 pdlg->loc_uri.len = strlen (pdlg->loc_uri.s);
 pdlg->rem_uri.s = ptob->uri.s;
 pdlg->rem_uri.len = ptob->uri.len;
+if (pdsturi->s)
+  {
+  pdlg->dst_uri.s = pdsturi->s;
+  pdlg->dst_uri.len = pdsturi->len;
+  }
 return pdlg;
 }
 
@@ -1171,7 +1322,7 @@ rtpmap **pmohfiles = find_MOH (pcall->pmohq->mohq_mohdir,
   pcall->pmohq->mohq_mohfile);
 if (!pmohfiles [0])
   {
-  LM_ERR ("%sUnable to find any MOH files for queue (%s)!", pfncname,
+  LM_ERR ("%sUnable to find any MOH files for queue (%s)!\n", pfncname,
     pcall->pmohq->mohq_name);
   return 0;
   }
@@ -1191,7 +1342,7 @@ for (nidx = 0; pmohfiles [nidx]; nidx++)
 pstr->s = pkg_malloc (nsize + 1);
 if (!pstr->s)
   {
-  LM_ERR ("%sNo more memory!", pfncname);
+  LM_ERR ("%sNo more memory!\n", pfncname);
   return 0;
   }
 strcpy (pstr->s, pSDP);
@@ -1238,7 +1389,7 @@ static void
 call_lst *pcall = (call_lst *)*pcbp->param;
 if (ntype == TMCB_DESTROY)
   { pcall->call_hash = pcall->call_label = 0; }
-LM_ERR ("invite_cb: INVITE failed for call (%s)!", pcall->call_from);
+LM_ERR ("invite_cb: INVITE failed for call (%s)!\n", pcall->call_from);
 delete_call (pcall);
 return;
 }
@@ -1249,10 +1400,10 @@ return;
 * INPUT:
 *   Arg (1) = SIP message pointer
 *   Arg (2) = call pointer
-* OUTPUT: 0=failed
+* OUTPUT: none
 **********/
 
-int notify_msg (sip_msg_t *pmsg, call_lst *pcall)
+void notify_msg (sip_msg_t *pmsg, call_lst *pcall)
 
 {
 /**********
@@ -1262,11 +1413,11 @@ int notify_msg (sip_msg_t *pmsg, call_lst *pcall)
 char *pfncname = "notify_msg: ";
 if (pcall->call_state != CLSTA_RFRWAIT)
   {
-  LM_ERR ("%sNot waiting on a REFER for call (%s)!", pfncname,
+  LM_ERR ("%sNot waiting on a REFER for call (%s)!\n", pfncname,
     pcall->call_from);
   if (pmod_data->psl->freply (pmsg, 481, presp_nocall) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
-  return 1;
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+  return;
   }
 
 /**********
@@ -1277,28 +1428,28 @@ if (pcall->call_state != CLSTA_RFRWAIT)
 
 if (!search_hdr_ext (pmsg->content_type, psipfrag))
   {
-  LM_ERR ("%sNot a %s type for call (%s)!", pfncname,
+  LM_ERR ("%sNot a %s type for call (%s)!\n", pfncname,
     psipfrag->s, pcall->call_from);
   if (pmod_data->psl->freply (pmsg, 415, presp_unsupp) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
-  return 1;
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+  return;
   }
 char *pfrag = get_body (pmsg);
 if (!pfrag)
   {
-  LM_ERR ("%s%s body missing for call (%s)!", pfncname,
+  LM_ERR ("%s%s body missing for call (%s)!\n", pfncname,
     psipfrag->s, pcall->call_from);
   if (pmod_data->psl->freply (pmsg, 415, presp_unsupp) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
-  return 1;
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+  return;
   }
 str pbody [1];
 pbody->len = pmsg->len - (int)(pfrag - pmsg->buf);
 pbody->s = pkg_malloc (pbody->len + 2);
 if (!pbody->s)
   {
-  LM_ERR ("%sNo more memory!", pfncname);
-  return 1;
+  LM_ERR ("%sNo more memory!\n", pfncname);
+  return;
   }
 strncpy (pbody->s, pfrag, pbody->len);
 if (pbody->s [pbody->len - 1] != '\n')
@@ -1311,10 +1462,10 @@ parse_first_line (pbody->s, pbody->len + 1, pstart);
 pkg_free (pbody->s);
 if (pstart->type != SIP_REPLY)
   {
-  LM_ERR ("%sReply missing for call (%s)!", pfncname, pcall->call_from);
+  LM_ERR ("%sReply missing for call (%s)!\n", pfncname, pcall->call_from);
   if (pmod_data->psl->freply (pmsg, 415, presp_unsupp) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
-  return 1;
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+  return;
   }
 
 /**********
@@ -1322,32 +1473,34 @@ if (pstart->type != SIP_REPLY)
 * o REFER done?
 **********/
 
+int nreply = pstart->u.reply.statuscode;
 if (pmod_data->psl->freply (pmsg, 200, presp_ok) < 0)
   {
-  LM_ERR ("%sUnable to create reply for call (%s)!",
+  LM_ERR ("%sUnable to create reply for call (%s)!\n",
     pfncname, pcall->call_from);
-  return 1;
+  return;
   }
-int nreply = pstart->u.reply.statuscode;
 mohq_debug (pcall->pmohq, "%sNOTIFY received reply (%d) for call (%s)",
   pfncname, nreply, pcall->call_from);
 switch (nreply / 100)
   {
   case 1:
+    pcall->refer_time = time (0);
     break;
   case 2:
     close_call (pmsg, pcall);
     break;
   default:
-    LM_WARN ("%sUnable to redirect call (%s)!", pfncname, pcall->call_from);
+    LM_WARN ("%sUnable to redirect call (%s)\n", pfncname, pcall->call_from);
     if (nreply == 487)
       {
       /**********
-      * call was canceled
+      * call was cancelled
       **********/
 
-      drop_call (pmsg, pcall);
-      return 1;
+      end_RTP (pmsg, pcall);
+      delete_call (pcall);
+      return;
       }
 
     /**********
@@ -1358,7 +1511,7 @@ switch (nreply / 100)
     update_call_rec (pcall);
     break;
   }
-return 1;
+return;
 }
 
 /**********
@@ -1367,10 +1520,10 @@ return 1;
 * INPUT:
 *   Arg (1) = SIP message pointer
 *   Arg (2) = call pointer
-* OUTPUT: 0=failed
+* OUTPUT: none
 **********/
 
-int prack_msg (sip_msg_t *pmsg, call_lst *pcall)
+void prack_msg (sip_msg_t *pmsg, call_lst *pcall)
 
 {
 /**********
@@ -1381,10 +1534,10 @@ char *pfncname = "prack_msg: ";
 tm_api_t *ptm = pmod_data->ptm;
 if (pcall->call_state != CLSTA_PRACKSTRT)
   {
-  LM_ERR ("%sUnexpected PRACK (%s)!", pfncname, pcall->call_from);
+  LM_ERR ("%sUnexpected PRACK (%s)!\n", pfncname, pcall->call_from);
   if (pmod_data->psl->freply (pmsg, 481, presp_nocall) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
-  return 1;
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+  return;
   }
 
 /**********
@@ -1394,20 +1547,20 @@ if (pcall->call_state != CLSTA_PRACKSTRT)
 
 if (ptm->t_newtran (pmsg) < 0)
   {
-  LM_ERR ("%sUnable to create new transaction for call (%s)!",
+  LM_ERR ("%sUnable to create new transaction for call (%s)!\n",
     pfncname, pcall->call_from);
   if (pmod_data->psl->freply (pmsg, 500, presp_srverr) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
-  return 1;
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+  return;
   }
 if (ptm->t_reply (pmsg, 200, presp_ok->s) < 0)
   {
-  LM_ERR ("%sUnable to reply to PRACK for call (%s)!",
+  LM_ERR ("%sUnable to reply to PRACK for call (%s)!\n",
     pfncname, pcall->call_from);
-  return 1;
+  return;
   }
 pcall->call_state = CLSTA_PRACKRPLY;
-return 1;
+return;
 }
 
 /**********
@@ -1448,18 +1601,22 @@ puri->s = pcall->call_referto;
 puri->len = strlen (puri->s);
 int npos1 = sizeof (prefermsg) // REFER template
   + strlen (pcall->call_via) // Via
+  + strlen (pcall->call_route) // Route
+  + strlen (pcall->pmohq->mohq_uri) // Contact
   + puri->len // Refer-To
-  + ptob->uri.len; // Referred-By
+  + strlen (pcall->pmohq->mohq_uri); // Referred-By
 char *pbuf = pkg_malloc (npos1);
 if (!pbuf)
   {
-  LM_ERR ("%sNo more memory!", pfncname);
+  LM_ERR ("%sNo more memory!\n", pfncname);
   goto refererr;
   }
 sprintf (pbuf, prefermsg,
   pcall->call_via, // Via
+  pcall->call_route, // Route
+  pcall->pmohq->mohq_uri, // Contact
   puri->s, // Refer-To
-  STR_FMT (&ptob->uri)); // Referred-By
+  pcall->pmohq->mohq_uri); // Referred-By
 
 /**********
 * send REFER request
@@ -1472,13 +1629,14 @@ phdrs->s = pbuf;
 phdrs->len = strlen (pbuf);
 set_uac_req (puac, prefer, phdrs, 0, pdlg,
   TMCB_LOCAL_COMPLETED | TMCB_ON_FAILURE, refer_cb, pcall);
+pcall->refer_time = time (0);
 pcall->call_state = CLSTA_REFER;
 update_call_rec (pcall);
 mohq_lock_release (plock);
 if (ptm->t_request_within (puac) < 0)
   {
   pcall->call_state = CLSTA_INQUEUE;
-  LM_ERR ("%sUnable to create REFER request for call (%s)!",
+  LM_ERR ("%sUnable to create REFER request for call (%s)!\n",
     pfncname, pcall->call_from);
   update_call_rec (pcall);
   goto refererr;
@@ -1512,21 +1670,23 @@ char *pfncname = "refer_cb: ";
 call_lst *pcall = (call_lst *)*pcbp->param;
 if ((ntype == TMCB_ON_FAILURE) || (pcbp->req == FAKED_REPLY))
   {
-  LM_ERR ("%sCall (%s) did not respond to REFER", pfncname,
+  LM_ERR ("%sCall (%s) did not respond to REFER!\n", pfncname,
     pcall->call_from);
-  drop_call (pcbp->req, pcall);
+  end_RTP (pcbp->req, pcall);
+  delete_call (pcall);
   return;
   }
 int nreply = pcbp->code;
 if ((nreply / 100) == 2)
   {
+  pcall->refer_time = time (0);
   pcall->call_state = CLSTA_RFRWAIT;
   mohq_debug (pcall->pmohq, "%sCall (%s) REFER reply=%d",
     pfncname, pcall->call_from, nreply);
   }
 else
   {
-  LM_ERR ("%sCall (%s) REFER error (%d)", pfncname,
+  LM_ERR ("%sCall (%s) REFER error (%d)!\n", pfncname,
     pcall->call_from, nreply);
   if (nreply == 481)
     { delete_call (pcall); }
@@ -1545,10 +1705,10 @@ return;
 * INPUT:
 *   Arg (1) = SIP message pointer
 *   Arg (2) = call pointer
-* OUTPUT: 0=failed
+* OUTPUT: none
 **********/
 
-int reinvite_msg (sip_msg_t *pmsg, call_lst *pcall)
+void reinvite_msg (sip_msg_t *pmsg, call_lst *pcall)
 
 {
 /**********
@@ -1563,17 +1723,17 @@ if ((pcall->call_state / 100) < 2)
   mohq_debug (pcall->pmohq, "%sINVITE still pending for call (%s)",
     pfncname, pcall->call_from);
   if (pmod_data->psl->freply (pmsg, 491, presp_reqpend) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
-  return 1;
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+  return;
   }
 if (!(pmsg->msg_flags & FL_SDP_BODY))
   {
   if (parse_sdp (pmsg))
     {
-    LM_ERR ("%sre-INVITE lacks SDP (%s)!", pfncname, pcall->call_from);
+    LM_ERR ("%sre-INVITE lacks SDP (%s)!\n", pfncname, pcall->call_from);
     if (pmod_data->psl->freply (pmsg, 488, presp_noaccept) < 0)
-      { LM_ERR ("%sUnable to create reply!", pfncname); }
-    return 1;
+      { LM_ERR ("%sUnable to create reply!\n", pfncname); }
+    return;
     }
   }
 
@@ -1643,12 +1803,12 @@ if (!bhold)
   {
   if (!bmatch)
     {
-    LM_ERR ("%sre-INVITE refused because no matching payload for call (%s)!",
+    LM_ERR ("%sre-INVITE refused because no matching payload for call (%s)!\n",
       pfncname, pcall->call_from);
     if (pmod_data->psl->freply (pmsg, 488, presp_noaccept) < 0)
       {
-      LM_ERR ("%sUnable to create reply!", pfncname);
-      return 1;
+      LM_ERR ("%sUnable to create reply!\n", pfncname);
+      return;
       }
     }
   else
@@ -1657,26 +1817,26 @@ if (!bhold)
       pfncname, pcall->call_from);
     if (pmod_data->psl->freply (pmsg, 200, presp_ok) < 0)
       {
-      LM_ERR ("%sUnable to create reply!", pfncname);
-      return 1;
+      LM_ERR ("%sUnable to create reply!\n", pfncname);
+      return;
       }
     }
-  return 1;
+  return;
   }
 
 /**********
 * hold not allowed, say good-bye
 **********/
 
-LM_ERR ("%sTerminating call (%s) because hold not allowed!",
+LM_ERR ("%sTerminating call (%s) because hold not allowed!\n",
   pfncname, pcall->call_from);
 if (pmod_data->psl->freply (pmsg, 200, presp_ok) < 0)
   {
-  LM_ERR ("%sUnable to create reply!", pfncname);
-  return 1;
+  LM_ERR ("%sUnable to create reply!\n", pfncname);
+  return;
   }
 close_call (pmsg, pcall);
-return 1;
+return;
 }
 
 /**********
@@ -1744,22 +1904,21 @@ char *phdrtmplt =
   "Accept-Language: en" SIPEOL
   "Require: 100rel" SIPEOL
   "RSeq: %d" SIPEOL
-  "User-Agent: " USRAGNT SIPEOL
   ;
 sprintf (phdrtmp, phdrtmplt, pcall->call_cseq);
 struct lump_rpl **phdrlump = add_lump_rpl2 (pmsg, phdrtmp,
   strlen (phdrtmp), LUMP_RPL_HDR);
 if (!phdrlump)
   {
-  LM_ERR ("%sUnable to create new header for call (%s)!",
+  LM_ERR ("%sUnable to create new header for call (%s)!\n",
     pfncname, pcall->call_from);
   if (pmod_data->psl->freply (pmsg, 500, presp_srverr) < 0)
-    { LM_ERR ("%sUnable to create reply!", pfncname); }
+    { LM_ERR ("%sUnable to create reply!\n", pfncname); }
   return 0;
   }
 if (ptm->t_reply (pmsg, 180, presp_ring->s) < 0)
   {
-  LM_ERR ("%sUnable to reply to INVITE for call (%s)",
+  LM_ERR ("%sUnable to reply to INVITE for call (%s)!\n",
     pfncname, pcall->call_from);
   return 0;
   }
@@ -1780,7 +1939,7 @@ while (1)
     { break; }
   if (nstart < time (0))
     {
-    LM_ERR ("%sNo PRACK response for call (%s)",
+    LM_ERR ("%sNo PRACK response for call (%s)!\n",
       pfncname, pcall->call_from);
     break;
     }
@@ -1820,7 +1979,7 @@ pbuf->s = build_res_buf_from_sip_req (200, presp_ok, ptotag, ptrans->uas.request
   (unsigned int *)&pbuf->len, pBM);
 if (!pbuf->s || !pbuf->len)
   {
-  LM_ERR ("%sUnable to create SDP response for call (%s)!",
+  LM_ERR ("%sUnable to create SDP response for call (%s)!\n",
     pfncname, pcall->call_from);
   return 0;
   }
@@ -1893,7 +2052,7 @@ npos1 += pextrahdr->len + strlen (pbodylen) + pSDP->len + 1;
 char *pnewbuf = pkg_malloc (npos1);
 if (!pnewbuf)
   {
-  LM_ERR ("%sNo more memory!", pfncname);
+  LM_ERR ("%sNo more memory!\n", pfncname);
   goto answer_done;
   }
 for (npos1 = npos2 = 0; npos2 < nhdrcnt; npos2++)
@@ -1923,7 +2082,7 @@ build_sip_msg_from_buf (pnmsg, pbuf->s, pbuf->len, 0);
 memcpy (&pnmsg->rcv, &pmsg->rcv, sizeof (struct receive_info));
 
 /**********
-* o send rtpproxy answer
+* o send RTP answer
 * o form stream file
 * o send stream
 **********/
@@ -1932,7 +2091,7 @@ mohq_debug (pcall->pmohq, "%sAnswering RTP link for call (%s)",
   pfncname, pcall->call_from);
 if (pmod_data->fn_rtp_answer (pnmsg, 0, 0) != 1)
   {
-  LM_ERR ("%srtpproxy_answer refused for call (%s)!",
+  LM_ERR ("%srtpproxy_answer refused for call (%s)!\n",
     pfncname, pcall->call_from);
   goto answer_done;
   }
@@ -1949,7 +2108,7 @@ pkg_free (pnewbuf);
 free_sip_msg (pnmsg);
 if (!pbuf->s || !pbuf->len)
   {
-  LM_ERR ("%sUnable to create SDP response for call (%s)!",
+  LM_ERR ("%sUnable to create SDP response for call (%s)!\n",
     pfncname, pcall->call_from);
   goto answer_done;
   }
@@ -1973,26 +2132,26 @@ char *pfnd = strstr (pnewSDP->s, "m=audio ");
 if (!pfnd)
   {
   // should not happen
-  LM_ERR ("%sUnable to find audio port for call (%s)!",
+  LM_ERR ("%sUnable to find audio port for call (%s)!\n",
     pfncname, pcall->call_from);
   goto answer_done;
   }
 pcall->call_aport = strtol (pfnd + 8, NULL, 10);
 if (!add_lump_rpl2 (pmsg, pextrahdr->s, pextrahdr->len, LUMP_RPL_HDR))
   {
-  LM_ERR ("%sUnable to add header for call (%s)!",
+  LM_ERR ("%sUnable to add header for call (%s)!\n",
     pfncname, pcall->call_from);
   goto answer_done;
   }
 if (!add_lump_rpl2 (pmsg, pnewSDP->s, pnewSDP->len, LUMP_RPL_BODY))
   {
-  LM_ERR ("%sUnable to add SDP body for call (%s)!",
+  LM_ERR ("%sUnable to add SDP body for call (%s)!\n",
     pfncname, pcall->call_from);
   goto answer_done;
   }
 if (ptm->t_reply (pmsg, 200, presp_ok->s) < 0)
   {
-  LM_ERR ("%sUnable to reply to INVITE for call (%s)!",
+  LM_ERR ("%sUnable to reply to INVITE for call (%s)!\n",
     pfncname, pcall->call_from);
   goto answer_done;
   }
@@ -2041,7 +2200,34 @@ mohq_debug (pcall->pmohq, "%sStarting RTP link for call (%s)",
   pfncname, pcall->call_from);
 if (fn_stream (pmsg, (char *)pmodel, (char *)-1) != 1)
   {
-  LM_ERR ("%srtpproxy_stream refused for call (%s)!",
+  LM_ERR ("%srtpproxy_stream refused for call (%s)!\n",
+    pfncname, pcall->call_from);
+  return 0;
+  }
+return 1;
+}
+
+/**********
+* Stop Streaming
+*
+* INPUT:
+*   Arg (1) = SIP message pointer
+*   Arg (2) = call pointer
+*   Arg (3) = server flag
+* OUTPUT: 0 if failed
+**********/
+
+int stop_stream (sip_msg_t *pmsg, call_lst *pcall, int bserver)
+
+{
+char *pfncname = "stop_stream: ";
+cmd_function fn_stop = bserver ? pmod_data->fn_rtp_stop_s
+  : pmod_data->fn_rtp_stop_c;
+mohq_debug (pcall->pmohq, "%sStopping RTP link for call (%s)",
+  pfncname, pcall->call_from);
+if (fn_stop (pmsg, (char *)-1, (char *)-1) != 1)
+  {
+  LM_ERR ("%srtpproxy_stop refused for call (%s)!\n",
     pfncname, pcall->call_from);
   return 0;
   }
@@ -2062,7 +2248,7 @@ char *form_tmpstr (str *pstr)
 char *pcstr = malloc (pstr->len + 1);
 if (!pcstr)
   {
-  LM_ERR ("No more memory!");
+  LM_ERR ("No more memory!\n");
   return NULL;
   }
 memcpy (pcstr, pstr->s, pstr->len);
@@ -2162,7 +2348,7 @@ struct mi_root *mi_debug (struct mi_root *pcmd_tree, void *parms)
 struct mi_node *pnode = pcmd_tree->node.kids;
 if (!pnode || !pnode->next || pnode->next->next)
   { return init_mi_tree (400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); }
-int nq_idx = find_queue (&pnode->value);
+int nq_idx = find_qname (&pnode->value);
 if (nq_idx == -1)
   { return init_mi_tree (400, pmi_noqueue->s, pmi_noqueue->len); }
 char pint [20];
@@ -2215,7 +2401,7 @@ struct mi_root *mi_drop_call (struct mi_root *pcmd_tree, void *parms)
 struct mi_node *pnode = pcmd_tree->node.kids;
 if (!pnode || !pnode->next || pnode->next->next)
   { return init_mi_tree (400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); }
-int nq_idx = find_queue (&pnode->value);
+int nq_idx = find_qname (&pnode->value);
 if (nq_idx == -1)
   { return init_mi_tree (400, pmi_noqueue->s, pmi_noqueue->len); }
 if (!mohq_lock_set (pmod_data->pcall_lock, 0, 5000))
@@ -2238,7 +2424,7 @@ for (nidx = 0; nidx < pmod_data->call_cnt; nidx++)
   **********/
 
   call_lst *pcall = &pmod_data->pcall_lst [nidx];
-  if (!pcall->call_active)
+  if (!pcall->call_state)
     { continue; }
   if (pqueue->mohq_id != pcall->pmohq->mohq_id)
     { continue; }
@@ -2277,12 +2463,12 @@ char *pfncname = "mohq_count: ";
 str pqname [1];
 if (!pqueue || !presult)
   {
-  LM_ERR ("%sParameters missing!", pfncname);
+  LM_ERR ("%sParameters missing!\n", pfncname);
   return -1;
   }
 if (fixup_get_svalue (pmsg, (gparam_p)pqueue, pqname))
   {
-  LM_ERR ("%sInvalid queue name!", pfncname);
+  LM_ERR ("%sInvalid queue name!\n", pfncname);
   return -1;
   }
 
@@ -2292,12 +2478,12 @@ if (fixup_get_svalue (pmsg, (gparam_p)pqueue, pqname))
 * o count items in queue
 **********/
 
-int nq_idx = find_queue (pqname);
+int nq_idx = find_qname (pqname);
 int ncount = 0;
 call_lst *pcalls = pmod_data->pcall_lst;
 int ncall_idx, mohq_id;
 if (!mohq_lock_set (pmod_data->pcall_lock, 0, 200))
-  { LM_ERR ("%sUnable to lock calls!", pfncname); }
+  { LM_ERR ("%sUnable to lock calls!\n", pfncname); }
 else
   {
   if (nq_idx != -1)
@@ -2305,7 +2491,7 @@ else
     mohq_id = pmod_data->pmohq_lst [nq_idx].mohq_id;
     for (ncall_idx = 0; ncall_idx < pmod_data->call_cnt; ncall_idx++)
       {
-      if (!pcalls [ncall_idx].call_active)
+      if (!pcalls [ncall_idx].call_state)
         { continue; }
       if (pcalls [ncall_idx].pmohq->mohq_id == mohq_id
         && pcalls [ncall_idx].call_state == CLSTA_INQUEUE)
@@ -2326,7 +2512,7 @@ pavp_val->ri = ncount;
 pavp_val->flags = PV_TYPE_INT | PV_VAL_INT;
 if (presult->setf (pmsg, &presult->pvp, (int)EQ_T, pavp_val) < 0)
   {
-  LM_ERR ("%sUnable to set pv value for mohq_count ()!", pfncname);
+  LM_ERR ("%sUnable to set pv value for mohq_count ()!\n", pfncname);
   return -1;
   }
 return 1;
@@ -2364,7 +2550,7 @@ va_list ap;
 va_start (ap, pfmt);
 vsnprintf (ptext, sizeof (ptext), pfmt, ap);
 va_end (ap);
-LM_DBG ("%s", ptext);
+LM_DBG ("%s\n", ptext);
 if (nsys_log < nmohq_log)
   { reset_local_debug_level (); }
 return;
@@ -2375,39 +2561,28 @@ return;
 *
 * INPUT:
 *   Arg (1) = SIP message pointer
-* OUTPUT: -1=not directed to queue; 1=successfully processed
+* OUTPUT: -1=not directed to queue or other error; 1=processed
 **********/
 
 int mohq_process (sip_msg_t *pmsg)
 
 {
 /**********
-* o parse headers
-* o lock MOH queue
-* o directed to message queue?
-* o connect to database
+* read lock queue and check for updates
 **********/
 
 char *pfncname = "mohq_process: ";
-if (parse_headers (pmsg, HDR_EOH_F, 0) < 0)
-  {
-  LM_ERR ("%sUnable to parse header!", pfncname);
-  return -1;
-  }
-if (!mohq_lock_set (pmod_data->pmohq_lock, 0, 2000))
+if (!mohq_lock_set (pmod_data->pmohq_lock, 0, 500))
   {
-  LM_ERR ("%sUnable to lock calls!", pfncname);
+  LM_ERR ("%sUnable to read lock queue!\n", pfncname);
   return -1;
   }
-call_lst *pcall;
-int mohq_idx = find_call (pmsg, &pcall);
 db1_con_t *pconn = mohq_dbconnect ();
 if (pconn)
   {
   /**********
   * o last update older than 1 minute?
-  * o exclusively lock MOH queue
-  * o update queue
+  * o update write locked queue
   **********/
 
   if (pmod_data->mohq_update + 60 < time (0))
@@ -2421,22 +2596,51 @@ if (pconn)
     }
   mohq_dbdisconnect (pconn);
   }
+
+/**********
+* o parse headers
+* o directed to message queue?
+* o write lock calls
+* o search for call
+* o release call lock
+**********/
+
+if (parse_headers (pmsg, HDR_EOH_F, 0) < 0)
+  {
+  mohq_lock_release (pmod_data->pmohq_lock);
+  LM_ERR ("%sUnable to parse header!\n", pfncname);
+  return -1;
+  }
+int mohq_idx = find_queue (pmsg);
 if (mohq_idx < 0)
   {
   mohq_lock_release (pmod_data->pmohq_lock);
   return -1;
   }
+if (!mohq_lock_set (pmod_data->pcall_lock, 1, 500))
+  {
+  mohq_lock_release (pmod_data->pmohq_lock);
+  LM_ERR ("%sUnable to write lock calls!\n", pfncname);
+  return 1;
+  }
+call_lst *pcall = find_call (pmsg, mohq_idx);
+mohq_lock_release (pmod_data->pcall_lock);
+if (!pcall)
+  {
+  mohq_lock_release (pmod_data->pmohq_lock);
+  return 1;
+  }
 
 /**********
 * o process message
-* o release MOH queue
+* o release queue lock
 **********/
 
 mohq_debug (&pmod_data->pmohq_lst [mohq_idx],
   "%sProcessing %.*s, queue (%s)", pfncname,
   STR_FMT (&REQ_LINE (pmsg).method),
   pmod_data->pmohq_lst [mohq_idx].mohq_name);
-int ret;
+str *ptotag;
 switch (pmsg->REQ_METHOD)
   {
   case METHOD_INVITE:
@@ -2444,33 +2648,35 @@ switch (pmsg->REQ_METHOD)
     * initial INVITE?
     **********/
 
-    if (!pcall)
-      { ret = first_invite_msg (pmsg, mohq_idx); }
+    ptotag = &(get_to (pmsg)->tag_value);
+    if (!ptotag->len)
+      { ptotag = 0; }
+    if (!ptotag)
+      { first_invite_msg (pmsg, pcall); }
     else
-      { ret = reinvite_msg (pmsg, pcall); }
+      { reinvite_msg (pmsg, pcall); }
     break;
   case METHOD_NOTIFY:
-    ret = notify_msg (pmsg, pcall);
+    notify_msg (pmsg, pcall);
     break;
   case METHOD_PRACK:
-    ret = prack_msg (pmsg, pcall);
+    prack_msg (pmsg, pcall);
     break;
   case METHOD_ACK:
-    ret = ack_msg (pmsg, pcall);
+    ack_msg (pmsg, pcall);
     break;
   case METHOD_BYE:
-    ret = bye_msg (pmsg, pcall);
+    bye_msg (pmsg, pcall);
     break;
   case METHOD_CANCEL:
-    ret = cancel_msg (pmsg, pcall);
+    cancel_msg (pmsg, pcall);
     break;
   default:
     deny_method (pmsg, pcall);
-    ret = 1;
     break;
   }
 mohq_lock_release (pmod_data->pmohq_lock);
-return ret ? 1 : -1;
+return 1;
 }
 
 /**********
@@ -2495,28 +2701,28 @@ char *pfncname = "mohq_retrieve: ";
 str puri [1], pqname [1];
 if (!pqueue || !pURI)
   {
-  LM_ERR ("%sParameters missing!", pfncname);
+  LM_ERR ("%sParameters missing!\n", pfncname);
   return -1;
   }
 if (fixup_get_svalue (pmsg, (gparam_p)pqueue, pqname))
   {
-  LM_ERR ("%sInvalid queue name!", pfncname);
+  LM_ERR ("%sInvalid queue name!\n", pfncname);
   return -1;
   }
 if (fixup_get_svalue (pmsg, (gparam_p)pURI, puri))
   {
-  LM_ERR ("%sInvalid URI!", pfncname);
+  LM_ERR ("%sInvalid URI!\n", pfncname);
   return -1;
   }
 if (puri->len > URI_LEN)
   {
-  LM_ERR ("%sURI too long!", pfncname);
+  LM_ERR ("%sURI too long!\n", pfncname);
   return -1;
   }
 struct sip_uri puri_parsed [1];
 if (parse_uri (puri->s, puri->len, puri_parsed))
   {
-  LM_ERR ("%sInvalid URI (%.*s)!", pfncname, STR_FMT (puri));
+  LM_ERR ("%sInvalid URI (%.*s)!\n", pfncname, STR_FMT (puri));
   return -1;
   }
 
@@ -2526,12 +2732,12 @@ if (parse_uri (puri->s, puri->len, puri_parsed))
 * o find oldest call
 **********/
 
-int nq_idx = find_queue (pqname);
+int nq_idx = find_qname (pqname);
 if (nq_idx == -1)
   { return -1; }
 if (!mohq_lock_set (pmod_data->pcall_lock, 0, 200))
   {
-  LM_ERR ("%sUnable to lock calls!", pfncname);
+  LM_ERR ("%sUnable to lock calls!\n", pfncname);
   return -1;
   }
 call_lst *pcall = 0;
@@ -2544,15 +2750,27 @@ for (ncall_idx = 0; ncall_idx < pmod_data->call_cnt; ncall_idx++)
   /**********
   * o active call?
   * o matching queue?
+  * o refer stuck?
   * o in queue?
   * o check age
   **********/
 
   pcall = &pmod_data->pcall_lst [ncall_idx];
-  if (!pcall->call_active)
+  if (!pcall->call_state)
     { continue; }
   if (pcall->pmohq->mohq_id != mohq_id)
     { continue; }
+  if ((pcall->call_state == CLSTA_REFER)
+    || (pcall->call_state == CLSTA_RFRWAIT))
+    {
+    if ((pcall->refer_time + 32) < time (0))
+      {
+      LM_ERR
+        ("%sDropping call because no response to REFER for call (%s)!\n",
+        pfncname, pcall->call_from);
+      close_call (FAKED_REPLY, pcall);
+      }
+    }
   if (pcall->call_state != CLSTA_INQUEUE)
     { continue; }
   if (!ntime)
@@ -2571,7 +2789,7 @@ for (ncall_idx = 0; ncall_idx < pmod_data->call_cnt; ncall_idx++)
   }
 if (nfound == -1)
   {
-  LM_WARN ("%sNo calls in queue (%.*s)", pfncname, STR_FMT (pqname));
+  LM_WARN ("%sNo calls in queue (%.*s)\n", pfncname, STR_FMT (pqname));
   mohq_lock_release (pmod_data->pcall_lock);
   return -1;
   }
@@ -2586,7 +2804,7 @@ strncpy (pcall->call_referto, puri->s, puri->len);
 pcall->call_referto [puri->len] = '\0';
 if (refer_call (pcall, pmod_data->pcall_lock))
   { return 1; }
-LM_ERR ("%sUnable to refer call (%s)!", pfncname, pcall->call_from);
+LM_ERR ("%sUnable to refer call (%s)!\n", pfncname, pcall->call_from);
 return -1;
 }
 
@@ -2610,24 +2828,24 @@ int mohq_send (sip_msg_t *pmsg, char *pqueue)
 char *pfncname = "mohq_send: ";
 if (pmsg->REQ_METHOD != METHOD_INVITE)
   {
-  LM_ERR ("%sNot an INVITE message!", pfncname);
+  LM_ERR ("%sNot an INVITE message!\n", pfncname);
   return -1;
   }
 to_body_t *pto_body = get_to (pmsg);
 if (pto_body->tag_value.len)
   {
-  LM_ERR ("%sNot a first INVITE message!", pfncname);
+  LM_ERR ("%sNot a first INVITE message!\n", pfncname);
   return -1;
   }
 str pqname [1];
 if (!pqueue)
   {
-  LM_ERR ("%sParameters missing!", pfncname);
+  LM_ERR ("%sParameters missing!\n", pfncname);
   return -1;
   }
 if (fixup_get_svalue (pmsg, (gparam_p)pqueue, pqname))
   {
-  LM_ERR ("%sInvalid queue name!", pfncname);
+  LM_ERR ("%sInvalid queue name!\n", pfncname);
   return -1;
   }
 
@@ -2637,14 +2855,14 @@ if (fixup_get_svalue (pmsg, (gparam_p)pqueue, pqname))
 * o relay message
 **********/
 
-int nq_idx = find_queue (pqname);
+int nq_idx = find_qname (pqname);
 if (nq_idx == -1)
   { return -1; }
 str pruri [1] = {{0, strlen (pmod_data->pmohq_lst [nq_idx].mohq_uri)}};
 pruri->s = pkg_malloc (pruri->len + 1);
 if (!pruri->s)
   {
-  LM_ERR ("%sNo more memory!", pfncname);
+  LM_ERR ("%sNo more memory!\n", pfncname);
   return -1;
   }
 strcpy (pruri->s, pmod_data->pmohq_lst [nq_idx].mohq_uri);
@@ -2656,8 +2874,8 @@ pmsg->parsed_uri_ok = 0;
 pmsg->parsed_orig_ruri_ok = 0;
 if (pmod_data->ptm->t_relay (pmsg, 0, 0) < 0)
   {
-  LM_ERR ("%sUnable to relay INVITE!", pfncname);
+  LM_ERR ("%sUnable to relay INVITE!\n", pfncname);
   return -1;
   }
 return 1;
-}
+}
\ No newline at end of file
diff --git a/modules/mohqueue/mohq_funcs.h b/modules/mohqueue/mohq_funcs.h
index dbe02c5..5d4dfd1 100644
--- a/modules/mohqueue/mohq_funcs.h
+++ b/modules/mohqueue/mohq_funcs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -35,4 +35,4 @@ int mohq_process (sip_msg_t *);
 int mohq_retrieve (sip_msg_t *, char *, char *);
 int mohq_send (sip_msg_t *, char *);
 
-#endif /* MOHQ_FUNCS_H */
+#endif /* MOHQ_FUNCS_H */
\ No newline at end of file
diff --git a/modules/mohqueue/mohq_locks.c b/modules/mohqueue/mohq_locks.c
index 7adb04b..50ecb1c 100644
--- a/modules/mohqueue/mohq_locks.c
+++ b/modules/mohqueue/mohq_locks.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -101,12 +101,12 @@ char *pfncname = "mohq_lock_init: ";
 plock->plock = lock_alloc ();
 if (!plock->plock)
   {
-  LM_ERR ("%sUnable to allocate lock memory!", pfncname);
+  LM_ERR ("%sUnable to allocate lock memory!\n", pfncname);
   return 0;
   }
 if (!lock_init (plock->plock))
   {
-  LM_ERR ("%sUnable to init lock!", pfncname);
+  LM_ERR ("%sUnable to init lock!\n", pfncname);
   lock_dealloc (plock->plock);
   return 0;
   }
@@ -138,7 +138,7 @@ switch (plock->lock_cnt)
     plock->lock_cnt = 0;
     break;
   case 0:
-    LM_WARN ("mohq_lock_release: Lock was not set");
+    LM_WARN ("mohq_lock_release: Lock was not set.\n");
     break;
   default:
     plock->lock_cnt--;
@@ -194,4 +194,4 @@ do
   }
 while (!nret && --nms_cnt >= 0);
 return nret;
-}
+}
\ No newline at end of file
diff --git a/modules/mohqueue/mohq_locks.h b/modules/mohqueue/mohq_locks.h
index 6f95c65..18c23fe 100644
--- a/modules/mohqueue/mohq_locks.h
+++ b/modules/mohqueue/mohq_locks.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Robert Boisvert
+ * Copyright (C) 2013-15 Robert Boisvert
  *
  * This file is part of the mohqueue module for Kamailio, a free SIP server.
  *
@@ -44,4 +44,4 @@ int mohq_lock_init (mohq_lock *);
 void mohq_lock_release (mohq_lock *);
 int mohq_lock_set (mohq_lock *, int, int);
 
-#endif /* MOHQ_LOCKS_H */
+#endif /* MOHQ_LOCKS_H */
\ No newline at end of file
diff --git a/main/kamailio/0003-kamdbctl-backslash.patch b/main/kamailio/0003-kamdbctl-backslash.patch
index 085b22b..e87b620 100644
--- a/main/kamailio/0003-kamdbctl-backslash.patch
+++ b/main/kamailio/0003-kamdbctl-backslash.patch
@@ -1,5 +1,5 @@
diff --git a/utils/kamctl/kamdbctl.base b/utils/kamctl/kamdbctl.base
index bb74810..20780ef 100644
index 3daf457..b60413c 100644
--- a/utils/kamctl/kamdbctl.base
+++ b/utils/kamctl/kamdbctl.base
@@ -33,18 +33,18 @@ INSTALL_DBUID_TABLES=${INSTALL_DBUID_TABLES:-ask}
@@ -14,17 +14,16 @@ index bb74810..20780ef 100644
+		grp uri speed_dial lcr_gw lcr_rule lcr_rule_target pdt subscriber \
+		location location_attrs re_grp trusted address missed_calls \
+		usr_preferences aliases silo dialog dialog_vars dispatcher dialplan \
 		acc_cdrs}
 		acc_cdrs topos_d topos_t}
-EXTRA_TABLES=${EXTRA_TABLES:-imc_members imc_rooms cpl sip_trace domainpolicy
-		carrierroute carrier_name domain_name carrierfailureroute userblacklist
-		globalblacklist htable purplemap uacreg pl_pipes mtree mtrees
-		sca_subscriptions mohqcalls mohqueues rtpproxy}
-PRESENCE_TABLES=${PRESENCE_TABLES:-presentity active_watchers watchers xcap 
+EXTRA_TABLES=${EXTRA_TABLES:-imc_members imc_rooms cpl sip_trace domainpolicy \
+		carrierroute carrier_name domain_name carrierfailureroute userblacklist \
+		globalblacklist htable purplemap uacreg pl_pipes mtree mtrees \
+		sca_subscriptions mohqcalls mohqueues rtpproxy} 
+PRESENCE_TABLES=${PRESENCE_TABLES:-presentity active_watchers watchers xcap \
 		sca_subscriptions mohqcalls mohqueues rtpproxy}
-PRESENCE_TABLES=${PRESENCE_TABLES:-presentity active_watchers watchers xcap 
+PRESENCE_TABLES=${PRESENCE_TABLES:-presentity active_watchers watchers xcap \ 
 		pua rls_presentity rls_watchers}
-DBUID_TABLES=${UID_TABLES:-uid_credentials uid_domain uid_domain_attrs
+DBUID_TABLES=${UID_TABLES:-uid_credentials uid_domain uid_domain_attrs \
@@ -39,7 +38,7 @@ index bb74810..20780ef 100644
-		permissions registrar usrloc msilo alias_db uri_db speeddial
+STANDARD_MODULES=${STANDARD_MODULES:-standard acc lcr domain group \
+		permissions registrar usrloc msilo alias_db uri_db speeddial \
 		avpops auth_db pdt dialog dispatcher dialplan}
 		avpops auth_db pdt dialog dispatcher dialplan topos}
 
 PRESENCE_MODULES=${PRESENCE_MODULES:-presence rls}
 
diff --git a/main/kamailio/0004-remove-spurious-execinfo.patch b/main/kamailio/0004-remove-spurious-execinfo.patch
new file mode 100644
index 0000000..161bee3
--- /dev/null
+++ b/main/kamailio/0004-remove-spurious-execinfo.patch
@@ -0,0 +1,30 @@
diff --git a/modules/ims_dialog/dlg_hash.c b/modules/ims_dialog/dlg_hash.c
index 26817ac..0f340b0 100644
--- a/modules/ims_dialog/dlg_hash.c
+++ b/modules/ims_dialog/dlg_hash.c
@@ -17,7 +17,8 @@
 #include "dlg_profile.h"
 #include "dlg_handlers.h"
 #include "dlg_db_handler.h"
-#include <execinfo.h>
+
+// #include <execinfo.h>
 
 #define MAX_LDG_LOCKS  2048
 #define MIN_LDG_LOCKS  2
@@ -70,6 +71,7 @@ static int dlg_hash_size_out = 4096;
 		}\
 	}while(0)
 
+#ifdef ALPINE_SUPPORTS_BACKTRACE
 inline static int backtrace2str(char* buf, int size)
 {
         void* bt[32];
@@ -87,6 +89,7 @@ inline static int backtrace2str(char* buf, int size)
         }
         return 0;
 }
+#endif
 
 /*!
  * \brief Initialize the global dialog table
diff --git a/main/kamailio/APKBUILD b/main/kamailio/APKBUILD
index 2ff4577..093add8 100644
--- a/main/kamailio/APKBUILD
+++ b/main/kamailio/APKBUILD
@@ -12,7 +12,7 @@ _giturl="git://github.com/$pkgname/$pkgname.git"
_gittag=HEAD


pkgver=4.3.5
pkgver=4.4.0
pkgrel=0
[ -z "${_gitcommit}" ] && _suffix="_src" || _suffix="-${_gitcommit}"

@@ -28,7 +28,7 @@ makedepends="bison flex expat-dev postgresql-dev pcre-dev mariadb-dev
	libxml2-dev curl-dev unixodbc-dev confuse-dev ncurses-dev sqlite-dev
	lua-dev openldap-dev openssl-dev net-snmp-dev libuuid libev-dev
	jansson-dev json-c-dev libevent-dev linux-headers libmemcached-dev
	hiredis-dev libmaxminddb-dev"
	hiredis-dev libmaxminddb-dev libunistring-dev"
install="$pkgname.pre-install $pkgname.pre-upgrade"

# See Makefile.groups for the list of recommended modules for
@@ -44,17 +44,17 @@ install="$pkgname.pre-install $pkgname.pre-upgrade"
# Remove db_text from _mod_list_db because we create a separate dbtext package
#
# - basic used modules, with no extra dependency (widespread usage)
_mod_list_basic="avp async auth benchmark blst cfg_rpc cfgutils corex counters \
_mod_list_basic="avp async auth benchmark blst cfg_rpc cfgt cfgutils corex counters \
		ctl debugger diversion enum exec gzcompress ipops kex mangler \
		maxfwd mediaproxy mi_datagram mi_fifo mi_rpc mqueue \
		nat_traversal nathelper path pike pv ratelimit rr rtimer \
		rtpproxy sanity sdpops siputils sl statistics textops \
		textopsx tm tmx topoh xlog rtpengine stun sipt"
		rtpproxy sanity sdpops siputils sl smsops statsc statistics \
		textops textopsx tm tmx topoh topos xlog rtpengine stun sipt"

# - extra used modules, with no extra dependency
_mod_list_extras="auth_diameter call_control cnxcc dmq domainpolicy msrp pdb \
		qos sca seas sms sst timer tmrec tsilo uac_redirect xhttp \
		xhttp_rpc xprint nosip dmq_usrloc statsd rtjson tcpops \
_mod_list_extras="auth_diameter call_control cnxcc dmq domainpolicy log_custom \
		msrp pdb qos sca seas sms sst timer tmrec tsilo uac_redirect \
		xhttp xhttp_rpc xprint nosip dmq_usrloc statsd rtjson tcpops \
		auth_xkeys"

# - common modules depending on database
@@ -114,7 +114,10 @@ _mod_list_carrierroute="carrierroute"
_mod_list_berkeley="db_berkeley"

# - modules depending on curl library
_mod_list_utils="utils"
_mod_list_utils="utils http_client"

# - async http_async_client
_mod_list_async_client="http_async_client"

# - modules depending on purple library
_mod_list_purple="purple"
@@ -123,7 +126,7 @@ _mod_list_purple="purple"
_mod_list_memcached="memcached"

# - modules depending on openssl library
_mod_list_tls="auth_identity tls"
_mod_list_tls="auth_identity crypto tls"

# - modules depending on openssl library
_mod_list_outbound="outbound"
@@ -176,7 +179,7 @@ _mod_list_redis="ndb_redis"
_mod_list_mono="app_mono"

# - modules related to IMS extensions
_mod_list_ims="cdp cdp_avp dialog_ng ims_auth ims_isc ims_icscf ims_qos \
_mod_list_ims="cdp cdp_avp ims_dialog ims_auth ims_isc ims_icscf ims_qos \
		ims_registrar_pcscf ims_registrar_scscf ims_usrloc_pcscf \
		ims_usrloc_scscf ims_charging"

@@ -222,7 +225,8 @@ for _i in db postgres sqlite dbtext mysql \
	cpl xml unixodbc snmpstats xmpp carrierroute \
	ldap utils tls presence lua ims outbound debugger \
	extras json websocket authephemeral \
	uuid ev memcached redis geoip2 jansson; do
	uuid ev memcached redis geoip2 jansson \
	http_async_client; do

   subpackages="$subpackages $pkgname-$_i"
   eval "_modules=\"\$_modules \$_mod_list_$_i\""
@@ -230,8 +234,8 @@ done

source="http://www.kamailio.org/pub/kamailio/$pkgver/src/${pkgname}-${pkgver}${_suffix}.tar.gz
	0001-musl-fixes.patch
	0002-mohqueue-v0-12.patch
	0003-kamdbctl-backslash.patch
	0004-remove-spurious-execinfo.patch
	kamailio.cfg
	kamailio.initd
	"
@@ -296,12 +300,13 @@ build() {
		DESTDIR="$pkgdir" \
		cfg_prefix="$pkgdir" \
		cfg
	make all EMBEDDED_UTF8_DECODE=1 || return 1
	make  EMBEDDED_UTF8_DECODE=1 STUN=1 \
		all || return 1
}

package() {
	cd "$_builddir"
	make  -j1 install EMBEDDED_UTF8_DECODE=1 || return 1
	make -j1 install || return 1

	# move default config to -doc package and use our own default config

@@ -497,21 +502,27 @@ redis() {
		"$_mod_list_redis"
}

md5sums="117e08e69a973cc0c0d63662d2f47109  kamailio-4.3.5_src.tar.gz
http_async_client() {
	_generic_pkg "Asynchronous HTTP queries support" \
		"$_mod_list_http_async_client"
}


md5sums="e9fa206f67346a6b01c015d76ec2db9d  kamailio-4.4.0_src.tar.gz
18863791d386659eae6ef0c82a2517ae  0001-musl-fixes.patch
324ce879bceac05b30aa9466bb74916d  0002-mohqueue-v0-12.patch
fe8f61c73264cd1c360f3876f664464d  0003-kamdbctl-backslash.patch
8c83bc9102a77711e30dcac6e9bba534  0003-kamdbctl-backslash.patch
e613ef3611f9a5091ce05084daf9c9a5  0004-remove-spurious-execinfo.patch
299706d97e30a4f0d9b4c873df422866  kamailio.cfg
39dc9355fa7d8fec425d3b17c2fb26e0  kamailio.initd"
sha256sums="2c8c963a2cd0c997c66ccc65b8d5de01fd7f4b6b6053bcf10bf746d814b313d5  kamailio-4.3.5_src.tar.gz
sha256sums="96b5aaac7980f21b022609846e85b2e4244f39b053d22a5e5f7efe5120cdf2b4  kamailio-4.4.0_src.tar.gz
254ea5d4699417aec49e1aae45398a802067a8967060f2a469e278779d876d22  0001-musl-fixes.patch
93e8ed5bbe16535286ab4cb586caf01cdf11f405492d36271108333210f0c58b  0002-mohqueue-v0-12.patch
46026949a3a367ebaf0c8a7d1ffeeaa3dc67588c94dd8d558991a54996877c1f  0003-kamdbctl-backslash.patch
9aa3b9afea6f0d2d8d306c2f7d093cb846189285e560ce3c62fa2ec2f3d461fe  0003-kamdbctl-backslash.patch
fb9c13dd3cd5cd07cf7599cf6688c46739334a18ade64f8bf44f84fb179e8409  0004-remove-spurious-execinfo.patch
8b742ff710ef67ff59ec07a260690ebcdda24fb6f0b7b64dc50433a1bacf99f2  kamailio.cfg
ba928fa914feea2b95b8c659832e3fbea25eb6ac1ce56e4c23ff58c09f1ec3b8  kamailio.initd"
sha512sums="73b28c0c8bfa8998091c6a40d74c5be057e1d8ad9838ac073bd8769fbf93448daf695040b49c432b87a38725a6debb3bd89a1080554e1f88e6fe8e305b535a87  kamailio-4.3.5_src.tar.gz
sha512sums="3a0df08c705df822f41e96a88cfdaba33db9c8cb3d38c12d858e2f99d5ead1c94a967033cce7e5119f2df64e2d34c383cdb7bf43f4ac52c61cf0323d9b70bf3b  kamailio-4.4.0_src.tar.gz
32c8e723ee858b24a3bd1313537e9348bdd895e709041d52199b7d2c4054565f3f8d203458b5a7bd5f4b09a782a972cf87f931de5bb8199e6f9786a3c9bfb3ba  0001-musl-fixes.patch
782e70cd6c17f37ca613b05c86a2ddca71b1f0d58361345ddecede2743de65095f058916e049db98e4033b937bcb7a94df77f4b5e1a78e1346d07c8d22dd51d5  0002-mohqueue-v0-12.patch
d96600f1047eac65c0eba34030baa26ee6ee953434ae5808b203cba979fbed616289d40fc588939222371d832f54cbda0a5e8ba9baa16913363e204490758167  0003-kamdbctl-backslash.patch
b71457ee4badf2c1848f4ea86afddfd2be2383791e559f5758fd8502d87e434f0149485eb1c33722d111999508b81b0acb56c9dcb462b6522a5f4cbfae05dfde  0003-kamdbctl-backslash.patch
d962f7bb7fe5c0747dff050d4c2d74f16eedba903a3347b3f86b42e5d7778f5f8b973a6134fd6714c0a62189bc475396e8225db3468390f6e1a84fc1d44f0d87  0004-remove-spurious-execinfo.patch
c1abf69b48847dc8c7ab0d11ef9adb531aa4635f9d44db6933981edc5a47df374664fb24867b19aa64abbcc9777bf1cd0360d9aea54e27b081065928c61e0f0b  kamailio.cfg
cd6e3b677d803cd78561ad14d9b2589fd35ad0096f48047fdcb4ddc7d9103871357efba3b350946844cb53dbb081210746421fc420c22ac845b90251168a628e  kamailio.initd"
-- 
2.7.4



---
Unsubscribe:  alpine-aports+unsubscribe@lists.alpinelinux.org
Help:         alpine-aports+help@lists.alpinelinux.org
---
Timo Teras <timo.teras@iki.fi>
Details
Message ID
<20160403201806.49e7125c@vostro>
In-Reply-To
<1459512894-6534-1-git-send-email-nangel@alpinelinux.org> (view parent)
Sender timestamp
1459703886
DKIM signature
missing
Download raw message
On Fri,  1 Apr 2016 12:14:54 +0000
Nathan Angelacos <nangel@alpinelinux.org> wrote:

> ---
>  main/kamailio/0002-mohqueue-v0-12.patch           | 2794
> ---------------------
> main/kamailio/0003-kamdbctl-backslash.patch       |   13 +-
> main/kamailio/0004-remove-spurious-execinfo.patch |   30 +
> main/kamailio/APKBUILD                            |   59 +- 4 files
> changed, 71 insertions(+), 2825 deletions(-) delete mode 100644
> main/kamailio/0002-mohqueue-v0-12.patch create mode 100644
> main/kamailio/0004-remove-spurious-execinfo.patch
> 
> diff --git a/main/kamailio/APKBUILD b/main/kamailio/APKBUILD
> index 2ff4577..093add8 100644
> --- a/main/kamailio/APKBUILD
> +++ b/main/kamailio/APKBUILD
> @@ -12,7 +12,7 @@ _giturl="git://github.com/$pkgname/$pkgname.git"
>  _gittag=HEAD
>  
>  
> -pkgver=4.3.5
> +pkgver=4.4.0
>  pkgrel=0
>  [ -z "${_gitcommit}" ] && _suffix="_src" || _suffix="-${_gitcommit}"

..

>  # - modules depending on curl library
> -_mod_list_utils="utils"
> +_mod_list_utils="utils http_client"
> +
> +# - async http_async_client
> +_mod_list_async_client="http_async_client"
  
..
 
> -md5sums="117e08e69a973cc0c0d63662d2f47109  kamailio-4.3.5_src.tar.gz
> +http_async_client() {
> +	_generic_pkg "Asynchronous HTTP queries support" \
> +		"$_mod_list_http_async_client"
> +}

Seems above you define only _mod_list_async_clients, but later refer to
_mod_list_http_async_client...  and the package I built ended up having
empty http_async_client subpkg. 

Otherwise looks good!


---
Unsubscribe:  alpine-aports+unsubscribe@lists.alpinelinux.org
Help:         alpine-aports+help@lists.alpinelinux.org
---
Reply to thread Export thread (mbox)