dlg_cb.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "../../mem/shm_mem.h"
00034 #include "../../dprint.h"
00035 #include "dlg_hash.h"
00036 #include "dlg_cb.h"
00037
00038
00039 static struct dlg_head_cbl* create_cbs = 0;
00040
00041 static struct dlg_head_cbl* load_cbs = 0;
00042
00043 static struct dlg_cb_params params = {NULL, DLG_DIR_NONE, NULL, NULL};
00044
00045
00046 #define POINTER_CLOSED_MARKER ((void *)(-1))
00047
00048
00049 static void run_load_callback(struct dlg_callback *cb);
00050
00051
00052
00053 static struct dlg_head_cbl* init_dlg_callback(void)
00054 {
00055 struct dlg_head_cbl *new_cbs;
00056
00057 new_cbs = (struct dlg_head_cbl*)shm_malloc(sizeof(struct dlg_head_cbl));
00058 if (new_cbs==0) {
00059 LM_ERR("no more shm mem\n");
00060 return 0;
00061 }
00062 new_cbs->first = 0;
00063 new_cbs->types = 0;
00064
00065 return new_cbs;
00066 }
00067
00068
00069 void destroy_dlg_callbacks_list(struct dlg_callback *cb)
00070 {
00071 struct dlg_callback *cb_t;
00072
00073 while(cb) {
00074 cb_t = cb;
00075 cb = cb->next;
00076 if (cb_t->callback_param_free && cb_t->param) {
00077 cb_t->callback_param_free(cb_t->param);
00078 cb_t->param = NULL;
00079 }
00080 shm_free(cb_t);
00081 }
00082 }
00083
00084
00085 void destroy_dlg_callbacks(unsigned int types)
00086 {
00087 if (types&DLGCB_CREATED) {
00088 if (create_cbs && create_cbs!=POINTER_CLOSED_MARKER) {
00089 destroy_dlg_callbacks_list(create_cbs->first);
00090 shm_free(create_cbs);
00091 create_cbs = POINTER_CLOSED_MARKER;
00092 }
00093 }
00094 if (types&DLGCB_LOADED) {
00095 if (load_cbs && load_cbs!=POINTER_CLOSED_MARKER) {
00096 destroy_dlg_callbacks_list(load_cbs->first);
00097 shm_free(load_cbs);
00098 load_cbs = POINTER_CLOSED_MARKER;
00099 }
00100 }
00101 }
00102
00103
00104 int register_dlgcb(struct dlg_cell *dlg, int types, dialog_cb f,
00105 void *param, param_free_cb ff )
00106 {
00107 struct dlg_callback *cb;
00108
00109 if ( types&DLGCB_LOADED ) {
00110 if (types!=DLGCB_LOADED) {
00111 LM_CRIT("DLGCB_LOADED type must be register alone!\n");
00112 return -1;
00113 }
00114 } else if ( types&DLGCB_CREATED ) {
00115 if (types!=DLGCB_CREATED) {
00116 LM_CRIT("DLGCB_CREATED type must be register alone!\n");
00117 return -1;
00118 }
00119 } else {
00120 if (dlg==0) {
00121 LM_CRIT("non-DLGCB_CREATED type "
00122 "must be register to a dialog (dlg missing)!\n");
00123 return -1;
00124 }
00125 }
00126 cb = (struct dlg_callback*)shm_malloc(sizeof(struct dlg_callback));
00127 if (cb==0) {
00128 LM_ERR("no more shm mem\n");
00129 return -1;
00130 }
00131
00132 cb->types = types;
00133 cb->callback = f;
00134 cb->param = param;
00135 cb->callback_param_free = ff;
00136
00137 if ( types==DLGCB_CREATED ) {
00138 if (load_cbs==POINTER_CLOSED_MARKER) {
00139 LM_CRIT("DLGCB_CREATED type registered after shutdown!?!\n");
00140 goto error;
00141 }
00142 if (create_cbs==0) {
00143
00144 if ( (create_cbs=init_dlg_callback())==NULL ) {
00145 LM_ERR("no more shm mem\n");
00146 goto error;
00147 }
00148 }
00149 cb->next = create_cbs->first;
00150 create_cbs->first = cb;
00151 create_cbs->types |= types;
00152 } else if (types==DLGCB_LOADED) {
00153 if (load_cbs==POINTER_CLOSED_MARKER) {
00154
00155 run_load_callback(cb);
00156 destroy_dlg_callbacks_list(cb);
00157 return 0;
00158 }
00159 if (load_cbs==0) {
00160
00161 if ( (load_cbs=init_dlg_callback())==NULL ) {
00162 LM_ERR("no more shm mem\n");
00163 goto error;
00164 }
00165 }
00166 cb->next = load_cbs->first;
00167 load_cbs->first = cb;
00168 load_cbs->types |= types;
00169 } else {
00170 cb->next = dlg->cbs.first;
00171 dlg->cbs.first = cb;
00172 dlg->cbs.types |= types;
00173 }
00174
00175 return 0;
00176 error:
00177 shm_free(cb);
00178 return -1;
00179 }
00180
00181
00182 static void run_load_callback(struct dlg_callback *cb)
00183 {
00184 struct dlg_cell *dlg;
00185 unsigned int i;
00186
00187 params.msg = NULL;
00188 params.direction = DLG_DIR_NONE;
00189 params.param = &cb->param;
00190
00191 for( i=0 ; i<d_table->size ; i++ ) {
00192 for( dlg=d_table->entries[i].first ; dlg ; dlg=dlg->next )
00193 cb->callback( dlg, DLGCB_LOADED, ¶ms );
00194 }
00195
00196 return;
00197 }
00198
00199
00200 void run_load_callbacks( void )
00201 {
00202 struct dlg_callback *cb;
00203
00204 if (load_cbs && load_cbs!=POINTER_CLOSED_MARKER) {
00205 for ( cb=load_cbs->first; cb; cb=cb->next )
00206 run_load_callback( cb );
00207 }
00208
00209 return;
00210 }
00211
00212
00213 void run_create_callbacks(struct dlg_cell *dlg, struct sip_msg *msg)
00214 {
00215 struct dlg_callback *cb;
00216
00217 if (create_cbs==NULL || create_cbs->first==NULL)
00218 return;
00219
00220 params.msg = msg;
00221
00222 params.direction = DLG_DIR_DOWNSTREAM;
00223
00224 params.param = NULL;
00225 params.dlg_data = NULL;
00226
00227 for ( cb=create_cbs->first; cb; cb=cb->next) {
00228 LM_DBG("dialog=%p\n",dlg);
00229 params.param = &cb->param;
00230 cb->callback( dlg, DLGCB_CREATED, ¶ms );
00231 }
00232 return;
00233 }
00234
00235
00236 void run_dlg_callbacks(int type , struct dlg_cell *dlg, struct sip_msg *msg,
00237 unsigned int dir, void *dlg_data)
00238 {
00239 struct dlg_callback *cb;
00240
00241 params.msg = msg;
00242 params.direction = dir;
00243 params.dlg_data = dlg_data;
00244
00245 if (dlg->cbs.first==0 || ((dlg->cbs.types)&type)==0 )
00246 return;
00247
00248 for ( cb=dlg->cbs.first; cb; cb=cb->next) {
00249 if ( (cb->types)&type ) {
00250 LM_DBG("dialog=%p, type=%d\n", dlg, type);
00251 params.param = &cb->param;
00252 cb->callback( dlg, type, ¶ms );
00253 }
00254 }
00255 return;
00256 }