dlg_state.c File Reference


Detailed Description

Proxy-CSCF - Dialog State.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

Alberto Diez - Support of release_call

Definition in file dlg_state.c.

#include <time.h>
#include "dlg_state.h"
#include "../../mem/shm_mem.h"
#include "../sl/sl_funcs.h"
#include "sip.h"
#include "release_call.h"
#include "ims_pm.h"

Go to the source code of this file.

Defines

#define strtotime(src, dest)
#define FParam_INT(val)
#define FParam_STRING(val)
#define h_inc   h+=v^(v>>3)

Functions

int supports_extension (struct sip_msg *m, str *extension)
int requires_extension (struct sip_msg *m, str *extension)
unsigned int get_p_dialog_hash (str call_id)
 Computes the hash for a string.
int p_dialogs_init (int hash_size)
 Initialize the registrar.
void p_dialogs_destroy ()
 Destroy the registrar.
void d_lock (unsigned int hash)
 Locks the required part of the hash table.
void d_unlock (unsigned int hash)
 UnLocks the required part of the hash table.
int d_act_time ()
 Actualize the current time.
void p_dialog_count_lock ()
 Locks the dialog counter variable.
void p_dialog_count_unlock ()
 UnLocks the dialog counter variable.
int p_dialog_count_increment ()
 Try to increment the dialog count.
void p_dialog_count_decrement ()
 Decrement the dialog count.
p_dialognew_p_dialog (str call_id, str host, int port, int transport)
 Creates a new p_dialog structure.
p_dialogadd_p_dialog (str call_id, str host, int port, int transport)
 Creates and adds a p_dialog to the hash table.
int is_p_dialog (str call_id, str host, int port, int transport, enum p_dialog_direction *dir)
 Finds out if a dialog is in the hash table.
int is_p_dialog_dir (str call_id, enum p_dialog_direction dir)
 Finds out if a dialog is in the hash table.
p_dialogget_p_dialog (str call_id, str host, int port, int transport, enum p_dialog_direction *dir)
 Finds and returns a dialog from the hash table.
p_dialogget_p_dialog_dir (str call_id, enum p_dialog_direction dir)
 Finds and returns a dialog from the hash table.
p_dialogget_p_dialog_dir_nolock (str call_id, enum p_dialog_direction dir)
 Finds and returns a dialog from the hash table.
int terminate_p_dialog (p_dialog *d)
 Terminates a dialog - called before del_p_dialog to send out terminatination messages.
void del_p_dialog (p_dialog *d)
 Deletes and destroys the dialog from the hash table.
void free_p_dialog (p_dialog *d)
 Destroys the dialog.
void print_p_dialogs (int log_level)
 Prints the dialog hash table.
static enum p_dialog_direction get_dialog_direction (char *direction)
 Returns the p_dialog_direction from the direction string.
static int find_dialog_contact (struct sip_msg *msg, enum p_dialog_direction dir, str *host, int *port, int *transport)
 Finds the contact host/port/transport for a dialog.
int P_is_in_dialog (struct sip_msg *msg, char *str1, char *str2)
 Find out if a message is within a saved dialog.
static enum p_dialog_method get_dialog_method (str method)
 Return p_dialog_method for a method string.
int P_422_session_expires (struct sip_msg *msg, char *str1, char *str2)
 Send a 422 Session Interval Too Small.
int P_check_session_expires (struct sip_msg *msg, char *str1, char *str2)
 Checks if Session-Expires value is over Min_SE local policy.
int P_save_dialog (struct sip_msg *msg, char *str1, char *str2)
 Saves a dialog.
void save_dialog_routes (struct sip_msg *msg, char *str1, p_dialog *d)
 Save the Record-routes for a dialog.
int update_dialog_on_reply (struct sip_msg *msg, p_dialog *d)
 Updates dialog on reply message.
int P_update_dialog (struct sip_msg *msg, char *str1, char *str2)
 Updates a dialog.
int P_drop_dialog (struct sip_msg *msg, char *str1, char *str2)
 Drops and deletes a dialog.
int P_drop_all_dialogs (str host, int port, int transport)
 Drop all dialogs belonging to one contact.
int P_follows_dialog_routes (struct sip_msg *msg, char *str1, char *str2)
 Checks if the message follows the saved dialog routes.
int P_enforce_dialog_routes (struct sip_msg *msg, char *str1, char *str2)
 Inserts the Route header containing the dialog routes to be enforced.
int P_record_route (struct sip_msg *msg, char *str1, char *str2)
 Record routes, with given user as parameter.
void dialog_timer (unsigned int ticks, void *param)
 The dialog timer looks for expired dialogs and removes them.

Variables

int p_dialogs_hash_size
 size of the dialog hash table
p_dialog_hash_slotp_dialogs = 0
 the hash table
int pcscf_dialogs_expiration_time
 expiration time for a dialog
int pcscf_dialogs_enable_release
 if to enable dialog release
time_t d_time_now
 current time for dialog updates
str pcscf_record_route_mo
 Record-route for originating case.
str pcscf_record_route_mo_uri
 URI for Record-route originating.
str pcscf_record_route_mt
 Record-route for terminating case.
str pcscf_record_route_mt_uri
 URI for Record-route terminating.
str pcscf_name_str
 fixed SIP URI of this P-CSCF
tm_binds tmb
 Structure with pointers to tm funcs.
int pcscf_min_se
 Minimum session-expires accepted value.
int(*) sl_reply (struct sip_msg *_msg, char *_str1, char *_str2)
 link to the stateless reply function in sl module
int * pcscf_dialog_count
 Counter for saved dialogs.
int pcscf_max_dialog_count
 Maximum number of dialogs.
gen_lock_t * pcscf_dialog_count_lock
 Lock for the dialog counter.
str reason_terminate_p_dialog_s = {"Session terminated in the P-CSCF",32}
str s_OTHER = {"<OTHER>",7}
str s_INVITE = {"INVITE",6}
str s_SUBSCRIBE = {"SUBSCRIBE",9}
static fparam_t fp_422 = FParam_INT(422)
static fparam_t fp_se_small = FParam_STRING("Session Interval Too Small")
static str s_refresher = {"refresher=", 10}
static str str_ext_timer = {"timer", 5}
static str str_min_se = {"Min-SE:",7}
static str str_se = {"Session-Expires:",16}
static str str_require = {"Require:",8}
static str route_s = {"Route: <",8}
static str route_1 = {">, <",4}
static str route_e = {">\r\n",3}
static str s_record_route_s = {"Record-Route: <",15}
static str s_record_route_e = {";lr>\r\n",6}


Define Documentation

#define strtotime ( src,
dest   ) 

Value:

{\
    int i;\
    (dest)=0;\
    for(i=0;i<(src).len;i++)\
        if ((src).s[i]>='0' && (src).s[i]<='9')\
            (dest) = (dest)*10 + (src).s[i] -'0';\
}

Definition at line 88 of file dlg_state.c.

#define FParam_INT ( val   ) 

Value:

{ \
     .v = { \
        .i = val \
     },\
    .type = FPARAM_INT, \
    .orig = "int_value", \
};

Definition at line 98 of file dlg_state.c.

#define FParam_STRING ( val   ) 

Value:

{ \
    .v = { \
        .str = STR_STATIC_INIT(val) \
    },\
    .type = FPARAM_STR, \
    .orig = val, \
};

Definition at line 106 of file dlg_state.c.

#define h_inc   h+=v^(v>>3)


Function Documentation

int supports_extension ( struct sip_msg *  m,
str *  extension 
)

Referenced by P_check_session_expires(), P_save_dialog(), P_update_dialog(), S_check_session_expires(), S_save_dialog(), and S_update_dialog().

int requires_extension ( struct sip_msg *  m,
str *  extension 
)

Referenced by update_dialog_on_reply().

unsigned int get_p_dialog_hash ( str  call_id  )  [inline]

Computes the hash for a string.

Parameters:
call_id - input string
Returns:
- the hash

Definition at line 120 of file dlg_state.c.

References h_inc, and p_dialogs_hash_size.

Referenced by bin_decode_p_dialog(), get_p_dialog(), get_p_dialog_dir(), get_p_dialog_dir_nolock(), is_p_dialog(), is_p_dialog_dir(), and new_p_dialog().

00121 {
00122     if (call_id.len==0) return 0;
00123 #define h_inc h+=v^(v>>3)
00124    char* p;
00125    register unsigned v;
00126    register unsigned h;
00127 
00128    h=0;
00129    for (p=call_id.s; p<=(call_id.s+call_id.len-4); p+=4){
00130        v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
00131        h_inc;
00132    }
00133    v=0;
00134    for (;p<(call_id.s+call_id.len); p++) {
00135        v<<=8;
00136        v+=*p;
00137    }
00138    h_inc;
00139 
00140    h=((h)+(h>>11))+((h>>13)+(h>>23));
00141    return (h)%p_dialogs_hash_size;
00142 #undef h_inc 
00143 }

int p_dialogs_init ( int  hash_size  ) 

Initialize the registrar.

Parameters:
hash_size - the number of hash table cells
Returns:
1 on success, 0 on error

Definition at line 150 of file dlg_state.c.

References p_dialog_hash_slot::lock, M_NAME, p_dialogs, and p_dialogs_hash_size.

Referenced by mod_init().

00151 {
00152     int i;
00153     
00154     p_dialogs_hash_size = hash_size;
00155     p_dialogs = shm_malloc(sizeof(p_dialog_hash_slot)*p_dialogs_hash_size);
00156 
00157     if (!p_dialogs) return 0;
00158 
00159     memset(p_dialogs,0,sizeof(p_dialog_hash_slot)*p_dialogs_hash_size);
00160     
00161     for(i=0;i<p_dialogs_hash_size;i++){
00162         p_dialogs[i].lock = lock_alloc();
00163         if (!p_dialogs[i].lock){
00164             LOG(L_ERR,"ERR:"M_NAME":d_hash_table_init(): Error creating lock\n");
00165             return 0;
00166         }
00167         p_dialogs[i].lock = lock_init(p_dialogs[i].lock);
00168     }
00169             
00170     return 1;
00171 }

void p_dialogs_destroy (  ) 

Destroy the registrar.

Definition at line 176 of file dlg_state.c.

References d_lock(), d_unlock(), free_p_dialog(), p_dialog_hash_slot::head, _p_dialog::next, p_dialogs, and p_dialogs_hash_size.

Referenced by mod_destroy().

00177 {
00178     int i;
00179     p_dialog *d,*nd;
00180     for(i=0;i<p_dialogs_hash_size;i++){
00181         d_lock(i);
00182             d = p_dialogs[i].head;
00183             while(d){
00184                 nd = d->next;
00185                 free_p_dialog(d);
00186                 d = nd;
00187             }
00188         d_unlock(i);
00189         lock_dealloc(p_dialogs[i].lock);
00190     }
00191     shm_free(p_dialogs);
00192 }

void d_lock ( unsigned int  hash  )  [inline]

Locks the required part of the hash table.

Parameters:
hash - hash of the element to lock (hash slot number)

Definition at line 198 of file dlg_state.c.

Referenced by add_p_dialog(), add_s_dialog(), bin_cache_dump_dialogs_to_table(), bin_cache_load_dialogs_from_table(), dialog_timer(), get_p_dialog(), get_p_dialog_dir(), get_s_dialog(), get_s_dialog_dir(), is_p_dialog(), is_p_dialog_dir(), is_s_dialog(), is_s_dialog_dir(), load_snapshot_dialogs(), make_snapshot_dialogs(), p_dialogs_destroy(), P_drop_all_dialogs(), print_p_dialogs(), print_s_dialogs(), s_dialogs_destroy(), and S_drop_all_dialogs().

00199 {
00200 //  LOG(L_CRIT,"GET %d\n",hash);
00201     lock_get(p_dialogs[(hash)].lock);
00202 //  LOG(L_CRIT,"GOT %d\n",hash);    
00203 }

void d_unlock ( unsigned int  hash  )  [inline]

UnLocks the required part of the hash table.

Parameters:
hash - hash of the element to lock (hash slot number)

Definition at line 209 of file dlg_state.c.

Referenced by bin_cache_dump_dialogs_to_table(), bin_cache_load_dialogs_from_table(), confirmed_response(), dialog_timer(), get_p_dialog(), get_p_dialog_dir(), get_s_dialog(), get_s_dialog_dir(), is_p_dialog(), is_p_dialog_dir(), is_s_dialog(), is_s_dialog_dir(), load_snapshot_dialogs(), make_snapshot_dialogs(), p_dialogs_destroy(), P_drop_all_dialogs(), P_drop_dialog(), P_enforce_dialog_routes(), P_follows_dialog_routes(), P_release_call_onreply(), P_save_dialog(), P_update_dialog(), print_p_dialogs(), print_s_dialogs(), release_call(), s_dialogs_destroy(), S_drop_all_dialogs(), S_drop_dialog(), S_save_dialog(), and S_update_dialog().

00210 {
00211     lock_release(p_dialogs[(hash)].lock);
00212 //  LOG(L_CRIT,"RELEASED %d\n",hash);   
00213 }

int d_act_time (  )  [inline]

Actualize the current time.

Returns:
the current time

Definition at line 219 of file dlg_state.c.

References d_time_now.

Referenced by dialog_timer(), P_save_dialog(), P_update_dialog(), print_p_dialogs(), print_s_dialogs(), S_save_dialog(), S_update_dialog(), and update_dialog_on_reply().

00220 {
00221     d_time_now=time(0);
00222     return d_time_now;
00223 }

void p_dialog_count_lock (  )  [inline]

Locks the dialog counter variable.

Definition at line 232 of file dlg_state.c.

References pcscf_dialog_count_lock.

Referenced by p_dialog_count_decrement(), and p_dialog_count_increment().

00233 {
00234     lock_get(pcscf_dialog_count_lock);
00235 }

void p_dialog_count_unlock (  )  [inline]

UnLocks the dialog counter variable.

Definition at line 240 of file dlg_state.c.

References pcscf_dialog_count_lock.

Referenced by p_dialog_count_decrement(), and p_dialog_count_increment().

00241 {
00242         lock_release(pcscf_dialog_count_lock);
00243 }

int p_dialog_count_increment (  )  [inline]

Try to increment the dialog count.

Returns:
1 on success or 0 if the total number of dialogs is already reached

Definition at line 250 of file dlg_state.c.

References M_NAME, p_dialog_count_lock(), p_dialog_count_unlock(), pcscf_dialog_count, and pcscf_max_dialog_count.

Referenced by new_p_dialog().

00251 {
00252     if (pcscf_max_dialog_count<0) return 1;
00253     p_dialog_count_lock();  
00254     if (*pcscf_dialog_count<pcscf_max_dialog_count){
00255         (*pcscf_dialog_count)++;
00256         p_dialog_count_unlock();
00257         return 1;
00258     } else {
00259         p_dialog_count_unlock();
00260         return 0;
00261     }
00262     LOG(L_DBG,"DBG:"M_NAME":p_dialog_count_increment(): P-CSCF Dialog counter value is %d\n", *pcscf_dialog_count);
00263 }

void p_dialog_count_decrement (  )  [inline]

Decrement the dialog count.

Definition at line 268 of file dlg_state.c.

References M_NAME, p_dialog_count_lock(), p_dialog_count_unlock(), pcscf_dialog_count, and pcscf_max_dialog_count.

Referenced by free_p_dialog(), and new_p_dialog().

00269 {
00270     if (pcscf_max_dialog_count<0) return ;
00271     p_dialog_count_lock();
00272     (*pcscf_dialog_count)--;
00273     p_dialog_count_unlock();
00274     LOG(L_DBG,"DBG:"M_NAME":p_dialog_count_decrement(): P-CSCF Dialog counter value is %d\n", *pcscf_dialog_count);    
00275 }

p_dialog* new_p_dialog ( str  call_id,
str  host,
int  port,
int  transport 
)

Creates a new p_dialog structure.

Does not add the structure to the list.

Parameters:
call_id - call-id of the dialog
host - host that originates/terminates this dialog
port - port that originates/terminates this dialog
transport - transport that originates/terminates this dialog
Returns:
the new p_dialog* on success, or NULL on error;

Definition at line 287 of file dlg_state.c.

References _p_dialog::call_id, get_p_dialog_hash(), _p_dialog::hash, _p_dialog::host, M_NAME, p_dialog_count_decrement(), p_dialog_count_increment(), _p_dialog::port, STR_SHM_DUP, and _p_dialog::transport.

Referenced by add_p_dialog().

00288 {
00289     p_dialog *d;
00290     
00291     if (!p_dialog_count_increment()) return 0;
00292     d = shm_malloc(sizeof(p_dialog));
00293     if (!d) {
00294         LOG(L_ERR,"ERR:"M_NAME":new_p_dialog(): Unable to alloc %d bytes\n",
00295             sizeof(p_dialog));
00296         goto error;
00297     }
00298     memset(d,0,sizeof(p_dialog));
00299     
00300     d->hash = get_p_dialog_hash(call_id);       
00301     STR_SHM_DUP(d->call_id,call_id,"shm");
00302     STR_SHM_DUP(d->host,host,"shm");    
00303     d->port = port;
00304     d->transport = transport;
00305                 
00306     return d;
00307 error:
00308 out_of_memory:
00309     if (d){
00310         if (d->call_id.s) shm_free(d->call_id.s);
00311         if (d->host.s) shm_free(d->host.s);
00312         shm_free(d);        
00313     }
00314     p_dialog_count_decrement();
00315     return 0;
00316 }

p_dialog* add_p_dialog ( str  call_id,
str  host,
int  port,
int  transport 
)

Creates and adds a p_dialog to the hash table.

Note:
Locks the hash slot if ok! Call d_unlock(p_dialog->hash) when you are finished)

make sure that is_p_dialog(call_id) returns 0 or there will be unreachable duplicates!

Parameters:
call_id - dialog's call_id
host - host that originates/terminates this dialog
port - port that originates/terminates this dialog
transport - transport that originates/terminates this dialog
Returns:
the new p_dialog* on success, or NULL on error;

Definition at line 328 of file dlg_state.c.

References d_lock(), _p_dialog::hash, p_dialog_hash_slot::head, new_p_dialog(), _p_dialog::next, p_dialogs, _p_dialog::prev, and p_dialog_hash_slot::tail.

Referenced by P_save_dialog().

00329 {
00330     p_dialog *d;
00331     
00332     d = new_p_dialog(call_id,host,port,transport);
00333     if (!d) return 0;       
00334     
00335     d_lock(d->hash);
00336         d->next = 0;
00337         d->prev = p_dialogs[d->hash].tail;
00338         if (d->prev) d->prev->next = d;
00339         p_dialogs[d->hash].tail = d;
00340         if (!p_dialogs[d->hash].head) p_dialogs[d->hash].head = d;
00341 
00342         return d;
00343 }

int is_p_dialog ( str  call_id,
str  host,
int  port,
int  transport,
enum p_dialog_direction dir 
)

Finds out if a dialog is in the hash table.

Parameters:
call_id - dialog's call_id
host - host that originates/terminates this dialog
port - port that originates/terminates this dialog
transport - transport that originates/terminates this dialog
dir - the direction of the dialog. if NULL, it doesn't matter
Returns:
- 1 if the dialog exists, 0 if not
Note:
transport is ignored.

Definition at line 355 of file dlg_state.c.

References _p_dialog::call_id, d_lock(), d_unlock(), _p_dialog::direction, get_p_dialog_hash(), p_dialog_hash_slot::head, _p_dialog::host, _p_dialog::next, p_dialogs, and _p_dialog::port.

Referenced by P_is_in_dialog(), and P_save_dialog().

00356 {
00357     p_dialog *d=0;
00358     unsigned int hash = get_p_dialog_hash(call_id);
00359 
00360     d_lock(hash);
00361         d = p_dialogs[hash].head;
00362         while(d){
00363             if ((!dir || d->direction == *dir) &&
00364                 d->port == port &&
00365 /*              d->transport == transport &&*/
00366 /* commented because of strange behaviour */
00367                 d->host.len == host.len &&
00368                 d->call_id.len == call_id.len &&
00369                 strncasecmp(d->host.s,host.s,host.len)==0 &&
00370                 strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) {
00371                     d_unlock(hash);
00372                     return 1;
00373                 }
00374             d = d->next;
00375         }
00376     d_unlock(hash);
00377     return 0;
00378 }

int is_p_dialog_dir ( str  call_id,
enum p_dialog_direction  dir 
)

Finds out if a dialog is in the hash table.

Parameters:
call_id - dialog's call_id
dir - the direction of the dialog
Returns:
- 1 if the dialog exists, 0 if not
Note:
transport is ignored.

Definition at line 387 of file dlg_state.c.

References _p_dialog::call_id, d_lock(), d_unlock(), _p_dialog::direction, get_p_dialog_hash(), p_dialog_hash_slot::head, _p_dialog::next, and p_dialogs.

Referenced by P_release_call_onreply().

00388 {
00389     p_dialog *d=0;
00390     unsigned int hash = get_p_dialog_hash(call_id);
00391         d_lock(hash);
00392         d = p_dialogs[hash].head;
00393         while(d){
00394             if (d->direction==dir && d->call_id.len == call_id.len &&
00395                         strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) {
00396                 d_unlock(hash);
00397                 return 1;
00398             }
00399             d=d->next;
00400         }
00401         d_unlock(hash);
00402         return 0;
00403 }

p_dialog* get_p_dialog ( str  call_id,
str  host,
int  port,
int  transport,
enum p_dialog_direction dir 
)

Finds and returns a dialog from the hash table.

Note:
Locks the hash slot if ok! Call d_unlock(p_dialog->hash) when you are finished)
Parameters:
call_id - dialog's call_id
host - host that originates/terminates this dialog
port - port that originates/terminates this dialog
transport - transport that originates/terminates this dialog
dir - the direction of the dialog. if NULL, it doesn't matter
Note:
transport is ignored.

Definition at line 415 of file dlg_state.c.

References _p_dialog::call_id, d_lock(), d_unlock(), _p_dialog::direction, get_p_dialog_hash(), p_dialog_hash_slot::head, _p_dialog::host, _p_dialog::next, p_dialogs, and _p_dialog::port.

Referenced by P_drop_dialog(), P_enforce_dialog_routes(), P_follows_dialog_routes(), and P_update_dialog().

00416 {
00417     p_dialog *d=0;
00418     unsigned int hash = get_p_dialog_hash(call_id);
00419 
00420     d_lock(hash);
00421         d = p_dialogs[hash].head;
00422         while(d){
00423             if ((!dir || d->direction == *dir) &&
00424                 d->port == port &&
00425 /*              d->transport == transport &&*/
00426 /* commented because of strange behaviour */
00427                 d->host.len == host.len &&
00428                 d->call_id.len == call_id.len &&
00429                 strncasecmp(d->host.s,host.s,host.len)==0 &&
00430                 strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) {
00431                     return d;
00432                 }
00433             d = d->next;
00434         }
00435     d_unlock(hash);
00436     return 0;
00437 }

p_dialog* get_p_dialog_dir ( str  call_id,
enum p_dialog_direction  dir 
)

Finds and returns a dialog from the hash table.

Parameters:
call_id - call_id of the dialog
dir - the direction
Returns:
the p_dialog* or NULL if not found

Definition at line 445 of file dlg_state.c.

References _p_dialog::call_id, d_lock(), d_unlock(), _p_dialog::direction, get_p_dialog_hash(), p_dialog_hash_slot::head, _p_dialog::next, and p_dialogs.

Referenced by confirmed_response(), P_release_call_onreply(), and release_call().

00446 {
00447     p_dialog *d=0;
00448     unsigned int hash = get_p_dialog_hash(call_id);
00449 
00450     d_lock(hash);
00451         d = p_dialogs[hash].head;
00452         while(d){
00453             if (d->direction == dir &&
00454                 d->call_id.len == call_id.len &&
00455                 strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) {
00456                     return d;
00457                 }
00458             d = d->next;
00459         }
00460     d_unlock(hash);
00461     return 0;
00462 }

p_dialog* get_p_dialog_dir_nolock ( str  call_id,
enum p_dialog_direction  dir 
)

Finds and returns a dialog from the hash table.

Note:
the table should be locked already for the call_id in the parameter
Parameters:
call_id - call_id of the dialog
dir - the direction
Returns:
the p_dialog* or NULL if not found

Definition at line 472 of file dlg_state.c.

References _p_dialog::call_id, _p_dialog::direction, get_p_dialog_hash(), p_dialog_hash_slot::head, _p_dialog::next, and p_dialogs.

Referenced by release_call_confirmed(), and release_call_previous().

00473 {
00474     p_dialog *d=0;
00475     unsigned int hash = get_p_dialog_hash(call_id);
00476 
00477     d = p_dialogs[hash].head;
00478     while(d){
00479         if (d->direction == dir &&
00480             d->call_id.len == call_id.len &&
00481             strncasecmp(d->call_id.s,call_id.s,call_id.len)==0) {
00482                 return d;
00483             }
00484         d = d->next;
00485     }
00486     return 0;
00487 }

int terminate_p_dialog ( p_dialog d  ) 

Terminates a dialog - called before del_p_dialog to send out terminatination messages.

Parameters:
d - the dialog to terminate
Returns:
- 1 if the requests were sent and the dialog will be deleted, 0 on error (you will have to delete the dialog yourself!)

Definition at line 496 of file dlg_state.c.

References del_p_dialog(), DLG_METHOD_INVITE, DLG_METHOD_SUBSCRIBE, M_NAME, _p_dialog::method, pcscf_dialogs_enable_release, reason_terminate_p_dialog_s, and release_call_p().

Referenced by dialog_timer().

00497 {
00498     if (!pcscf_dialogs_enable_release) return 0;
00499     switch (d->method){
00500         case DLG_METHOD_INVITE:
00501             if (release_call_p(d,503,reason_terminate_p_dialog_s)==-1){             
00502                 del_p_dialog(d);
00503             }
00504             return 1;
00505             break;
00506         case DLG_METHOD_SUBSCRIBE:
00507             LOG(L_ERR,"ERR:"M_NAME":terminate_p_dialog(): Not needed for SUBSCRIBE dialogs - silent drop on expiration.\n");
00508             return 0;
00509             break;
00510         default:
00511             LOG(L_ERR,"ERR:"M_NAME":terminate_p_dialog(): Not implemented yet for method[%d]!\n",d->method);
00512             return 0;
00513     }
00514 }

void del_p_dialog ( p_dialog d  ) 

Deletes and destroys the dialog from the hash table.

Note:
Must be called with a lock on the dialogs slot
Parameters:
d - the dialog to delete

Definition at line 521 of file dlg_state.c.

References free_p_dialog(), _p_dialog::hash, p_dialog_hash_slot::head, _p_dialog::next, p_dialogs, _p_dialog::prev, and p_dialog_hash_slot::tail.

Referenced by confirmed_response(), dialog_timer(), P_drop_all_dialogs(), P_drop_dialog(), P_save_dialog(), release_call_confirmed(), release_call_previous(), and terminate_p_dialog().

00522 {
00523     if (d->prev) d->prev->next = d->next;
00524     else p_dialogs[d->hash].head = d->next;
00525     if (d->next) d->next->prev = d->prev;
00526     else p_dialogs[d->hash].tail = d->prev;
00527     free_p_dialog(d);
00528 }

void free_p_dialog ( p_dialog d  ) 

Destroys the dialog.

Parameters:
d - the dialog to delete

Definition at line 534 of file dlg_state.c.

References _p_dialog::call_id, _p_dialog::dialog_c, _p_dialog::dialog_s, _p_dialog::host, _p_dialog::method_str, p_dialog_count_decrement(), _p_dialog::refresher, _p_dialog::routes, _p_dialog::routes_cnt, and tmb.

Referenced by del_p_dialog(), and p_dialogs_destroy().

00535 {
00536     int i;
00537     if (!d) return;
00538     if (d->call_id.s) shm_free(d->call_id.s);
00539     if (d->host.s) shm_free(d->host.s); 
00540     if (d->method_str.s) shm_free(d->method_str.s); 
00541     if (d->routes){
00542         for(i=0;i<d->routes_cnt;i++)
00543             shm_free(d->routes[i].s);
00544         shm_free(d->routes);
00545     }
00546     if (d->dialog_s) tmb.free_dlg(d->dialog_s);
00547     if (d->dialog_c) tmb.free_dlg(d->dialog_c);
00548     if (d->refresher.s) shm_free(d->refresher.s);
00549     shm_free(d);
00550     p_dialog_count_decrement(); 
00551 }

void print_p_dialogs ( int  log_level  ) 

Prints the dialog hash table.

Parameters:
log_level - the log_level to print with

Definition at line 557 of file dlg_state.c.

References ANSI_BLUE, ANSI_GREEN, ANSI_MAGENTA, ANSI_RED, ANSI_YELLOW, _p_dialog::call_id, d_act_time(), d_lock(), d_time_now, d_unlock(), _p_dialog::direction, _p_dialog::expires, p_dialog_hash_slot::head, _p_dialog::host, M_NAME, _p_dialog::method, _p_dialog::next, p_dialogs, p_dialogs_hash_size, _p_dialog::port, _p_dialog::routes, _p_dialog::state, and _p_dialog::transport.

Referenced by P_drop_dialog(), P_save_dialog(), and P_update_dialog().

00558 {
00559     p_dialog *d;
00560     int i,j;
00561     if (debug<log_level) return; /* to avoid useless calls when nothing will be printed */
00562     d_act_time();
00563     LOG(log_level,"INF:"M_NAME":----------  P-CSCF Dialog List begin --------------\n");
00564     for(i=0;i<p_dialogs_hash_size;i++){
00565         d_lock(i);
00566             d = p_dialogs[i].head;
00567             while(d){
00568                 LOG(log_level,"INF:"M_NAME":[%4d] Dir:["ANSI_MAGENTA"%d"ANSI_GREEN
00569                     "]\tCall-ID:<"ANSI_BLUE"%.*s"ANSI_GREEN
00570                     ">\tAOR:"ANSI_RED"%d://%.*s:%d"ANSI_GREEN"\n"
00571                     ,i,             
00572                     d->direction,
00573