- per new dialog callback, called each time a new UAS (DLG_CB_UAS) or UAC
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 24 Apr 2007 06:01:51 +0000 (06:01 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 24 Apr 2007 06:01:51 +0000 (06:01 +0000)
 (DLG_CB_UAC) is created (see dlg.h for details)
- per in-dialog sent message callback, called each time a new message is sent
 in a dialog (one should use the new dialog callback to register per message
 callbacks for the dialogs he is interested in)
Both of this callbacks are experimental and are disabled by default (one need
to compile with -DDIALOG_CALLBACKS or uncomment the correponding define in
dlg.h).

modules/tm/dlg.c
modules/tm/dlg.h
modules/tm/t_hooks.c
modules/tm/t_hooks.h
modules/tm/uac.c

index b6e59e4..141223b 100644 (file)
@@ -28,6 +28,7 @@
  * -------
  * 2003-03-29 Created by janakj
  * 2003-07-08 added wrapper to calculate_hooks, needed by b2bua (dcm)
+ * 2007-04-13 added dialog callbacks (andrei)
  */
 
 
 #define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)
 
 
+#ifdef DIALOG_CALLBACKS
+
+struct new_dlg_cb{
+       int types;
+       struct new_dlg_cb* next;
+       dialog_cb* callback;
+       void* param;
+};
+
+static struct new_dlg_cb* new_dlg_cb_list=0;
+/* callbacks for new dialogs (called each time a new dialog (uas or uac) is
+ * created)
+ * params: type - DLG_CB_UAC or DLG_CB_UAS
+ *            f - callback function
+ *        param - parameter passed to the callback; if allocated it must
+ *                  be allocated in shared mem.
+ * returns < 0 on error
+ * WARNING: this callbacks can be registered only before forking (in mod_init)
+ */
+int register_new_dlg_cb(int type, dialog_cb f, void* param)
+{
+       struct new_dlg_cb* dlg_cb;
+       
+       dlg_cb=shm_malloc(sizeof(struct new_dlg_cb));
+       if (dlg_cb==0)
+               return E_OUT_OF_MEM;
+       dlg_cb->types=type;
+       dlg_cb->callback=f;
+       dlg_cb->param=param;
+       dlg_cb->next=new_dlg_cb_list;
+       new_dlg_cb_list=dlg_cb;
+       return 0;
+}
+
+
+void destroy_new_dlg_cbs()
+{
+       struct new_dlg_cb* c;
+       struct new_dlg_cb* n;
+
+       c=new_dlg_cb_list;
+       while(c){
+               n=c->next;
+               shm_free(c);
+               c=n;
+       }
+       new_dlg_cb_list=0;
+}
+
+
+static void run_new_dlg_callbacks(int type, dlg_t* dlg, struct sip_msg* msg)
+{
+       struct new_dlg_cb* c;
+       for (c=new_dlg_cb_list; c; c=c->next){
+               if (c->types & type)
+                       c->callback(type, dlg, msg);
+       }
+}
+
+
+int register_dlg_tmcb(int types, dlg_t* dlg, transaction_cb f, void* param)
+{
+       if (types!=TMCB_DLG){
+               LOG(L_CRIT, "BUG: tm: register_dlg_tmcb: bad types %d\n", types);
+               return E_BUG;
+       }
+       if (f==0){
+               LOG(L_CRIT, "BUG: tm: register_dlg_tmcb: null callback function");
+               return E_BUG;
+       }
+       return insert_tmcb(&dlg->dlg_callbacks, types, f, param);
+}
+
+
+/* per dialog callbacks receive only the transaction, send buffer, destination
+ * and the retr. buff */
+void run_trans_dlg_callbacks(dlg_t* dlg, struct cell* trans,
+                                                               struct retr_buf* rbuf)
+{
+       struct tmcb_params params;
+       
+       if (dlg->dlg_callbacks.first==0)
+               return;
+       memset(&params, 0, sizeof(params));
+#ifdef TMCB_ONSEND
+       params.t_rbuf=rbuf;
+       params.dst=&rbuf->dst;
+       params.send_buf.s=rbuf->buffer;
+       params.send_buf.len=rbuf->buffer_len;
+#endif
+       
+       run_trans_callbacks_internal(&dlg->dlg_callbacks, TMCB_DLG, trans, 
+                                                                       &params);
+}
+
+#endif /* DIALOG_CALLBACKS */
+
 /*** Temporary hack ! */
 /*
  * This function skips name part
@@ -224,6 +322,9 @@ int new_dlg_uac(str* _cid, str* _ltag, unsigned int _lseq, str* _luri, str* _rur
                shm_free(res);
                return -2;
        }
+#ifdef DIALOG_CALLBACKS
+       run_new_dlg_callbacks(DLG_CB_UAC, res, 0);
+#endif
        
        return 0;
 }
@@ -866,6 +967,9 @@ int new_dlg_uas(struct sip_msg* _req, int _code, /*str* _tag,*/ dlg_t** _d)
                free_dlg(res);
                return -6;
        }
+#ifdef DIALOG_CALLBACKS
+       run_new_dlg_callbacks(DLG_CB_UAS, res, _req);
+#endif
 
        return 0;
 }
index 1c8af59..507e318 100644 (file)
@@ -26,6 +26,7 @@
  * History:
  * -------
  * 2003-03-29 Created by janakj
+ * 2007-04-13 added dialog callbacks (andrei)
  */
 
 #ifndef DLG_H
 #include "../../parser/parse_rr.h"
 #include "../../parser/msg_parser.h"
 
+/*
+#define DIALOG_CALLBACKS
+*/
+
+#ifdef DIALOG_CALLBACKS
+#include "t_hooks.h"
+#include "h_table.h"
+
+#define DLG_CB_UAC 30
+#define DLG_CB_UAS 31
+
+#endif /* DIALOG_CALLBACKS */
+
 
 /*
  * Dialog sequence
@@ -104,6 +118,9 @@ typedef struct dlg {
                                 * can be reused when building a message (to
                                 * prevent repeated analyzing of the dialog data
                                 */
+#ifdef DIALOG_CALLBACKS
+       struct tmcb_head_list dlg_callbacks;
+#endif
 } dlg_t;
 
 typedef enum {
@@ -183,4 +200,27 @@ typedef int (*calculate_hooks_f)(dlg_t* _d);
 int set_dlg_target(dlg_t* _d, str* _ruri, str* _duri);
 typedef int (*set_dlg_target_f)(dlg_t* _d, str* _ruri, str* _duri);
 
+#ifdef DIALOG_CALLBACKS
+
+/* dialog callback
+ * params:  type - DLG_UAC or DLG_UAS
+ *          dlg  - dialog structure
+ *          msg  - message used for creating the new dialog for the new_dlg_uas
+ *                 case, 0 otherwise (new_dlg_uac)
+ */
+typedef void (dialog_cb) (int type, dlg_t* dlg, struct sip_msg* msg);
+
+/* callbacks for new dialogs (called each time a new dialog (uas or uac) is
+ * created). Can be used for installing in-dialog callbacks
+ * returns < 0 on error*/
+int register_new_dlg_cb(int types, dialog_cb f, void* param);
+/* callbacks for messages sent dialogs */
+int register_dlg_tmcb(int type, dlg_t* dlg, transaction_cb f, void* param);
+void run_trans_dlg_callbacks(dlg_t* dlg, struct cell* trans,
+                                                               struct retr_buf* rbuf);
+/* cleanup on exit */
+void destroy_new_dlg_cbs();
+#endif /* DIALOG_CALLBACKS */
+
+
 #endif /* DLG_H */
index 73f82eb..b7f1123 100644 (file)
@@ -216,8 +216,9 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
 }
 
 
-static void run_trans_callbacks_internal(int type, struct cell *trans, 
-                                                                                       struct tmcb_params *params)
+void run_trans_callbacks_internal(struct tmcb_head_list* cb_lst, int type,
+                                                                       struct cell *trans, 
+                                                                       struct tmcb_params *params)
 {
        struct tm_callback    *cbp;
        avp_list_t* backup_from, *backup_to, *backup_dom_from, *backup_dom_to, *backup_uri_from, *backup_uri_to;
@@ -234,7 +235,7 @@ static void run_trans_callbacks_internal(int type, struct cell *trans,
                        &trans->domain_avps_from);
        backup_dom_to = set_avp_list(AVP_CLASS_DOMAIN | AVP_TRACK_TO, 
                        &trans->domain_avps_to);
-       for (cbp=trans->tmcb_hl.first; cbp; cbp=cbp->next)  {
+       for (cbp=cb_lst->first; cbp; cbp=cbp->next)  {
                if ( (cbp->types)&type ) {
                        DBG("DBG: trans=%p, callback type %d, id %d entered\n",
                                trans, type, cbp->id );
@@ -262,7 +263,7 @@ void run_trans_callbacks( int type , struct cell *trans,
        params.req = req;
        params.rpl = rpl;
        params.code = code;
-       run_trans_callbacks_internal(type, trans, &params);
+       run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
 }
 
 
@@ -286,7 +287,7 @@ void run_onsend_callbacks(int type, struct retr_buf* rbuf, int retr)
        params.t_rbuf=rbuf;
        params.code=rbuf->activ_type;
        /* req, rpl */
-       run_trans_callbacks_internal(type, trans, &params);
+       run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
 }
 
 
@@ -309,7 +310,7 @@ void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
        params.t_rbuf=rbuf;
        params.code=code;
        /* req, rpl */
-       run_trans_callbacks_internal(type, trans, &params);
+       run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
 }
 
 #endif
index d1e6d29..75902b2 100644 (file)
@@ -69,12 +69,13 @@ struct cell;
 #define TMCB_REQ_RETR_IN_N      11
 #define TMCB_LOCAL_RESPONSE_IN_N 12
 #define TMCB_LOCAL_REQUEST_IN_N  13
+#define TMCB_DLG_N              14
 #ifdef TMCB_ONSEND
-#define TMCB_REQUEST_SENT_N     14
-#define TMCB_RESPONSE_SENT_N    15
-#define TMCB_MAX_N              15
+#define TMCB_REQUEST_SENT_N     15
+#define TMCB_RESPONSE_SENT_N    16
+#define TMCB_MAX_N              16
 #else
-#define TMCB_MAX_N              13
+#define TMCB_MAX_N              14
 #endif
 
 #define TMCB_REQUEST_IN       (1<<TMCB_REQUEST_IN_N)
@@ -91,6 +92,7 @@ struct cell;
 #define TMCB_REQ_RETR_IN      (1<<TMCB_REQ_RETR_IN_N)
 #define TMCB_LOCAL_RESPONSE_IN (1<<TMCB_LOCAL_RESPONSE_IN_N)
 #define TMCB_LOCAL_REQUEST_IN (1<<TMCB_LOCAL_REQUEST_IN_N)
+#define TMCB_DLG              (1<<TMCB_DLG_N)
 #ifdef TMCB_ONSEND
 #define TMCB_REQUEST_SENT      (1<<TMCB_REQUEST_SENT_N)
 #define TMCB_RESPONSE_SENT     (1<<TMCB_RESPONSE_SENT_N)
@@ -371,7 +373,10 @@ int insert_tmcb(struct tmcb_head_list *cb_list, int types,
 /* run all transaction callbacks for an event type */
 void run_trans_callbacks( int type , struct cell *trans,
                                                struct sip_msg *req, struct sip_msg *rpl, int code );
-
+/* helper function */
+void run_trans_callbacks_internal(struct tmcb_head_list* cb_lst, int type,
+                                                                       struct cell *trans, 
+                                                                       struct tmcb_params *params);
 /* run all REQUEST_IN callbacks */
 void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );
 void run_local_reqin_callbacks( struct cell *trans, struct sip_msg *req, 
index 1289805..48ef53b 100644 (file)
@@ -55,6 +55,7 @@
  *  2006-08-11  t_uac uses dns failover until it finds a send socket (andrei)
  *  2007-03-15  TMCB_ONSEND callbacks support added (andrei)
  *  2007-03-23  TMCB_LOCAL_REQUEST_IN callbacks support (andrei)
+ *  2007-04-23  per dialog callbacks support (andrei)
  */
 
 #include <string.h>
@@ -297,6 +298,9 @@ static inline int t_uac_prepare(str* method, str* headers, str* body,
        
        if (has_local_reqin_tmcbs())
                        run_local_reqin_callbacks(new_cell, 0, 0);
+#ifdef DIALOG_CALLBACKS
+       run_trans_dlg_callbacks(dialog, new_cell, request);
+#endif /* DIALOG_CALLBACKS */
        if (dst_req) *dst_req = request;
        if (dst_cell) *dst_cell = new_cell;