dlg_state.h File Reference


Detailed Description

Proxy-CSCF - Dialog State.

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

Definition in file dlg_state.h.

#include "../../sr_module.h"
#include "mod.h"
#include "../../locking.h"
#include "../tm/dlg.h"
#include "../tm/tm_load.h"

Go to the source code of this file.

Data Structures

struct  _p_dialog
struct  p_dialog_hash_slot

Defines

#define DLG_METHOD_MAX   DLG_METHOD_SUBSCRIBE
 The last dialog type.

Typedefs

typedef _p_dialog p_dialog

Enumerations

enum  p_dialog_method { DLG_METHOD_OTHER = 0, DLG_METHOD_INVITE = 1, DLG_METHOD_SUBSCRIBE = 2 }
enum  p_dialog_state {
  DLG_STATE_UNKNOWN = 0, DLG_STATE_INITIAL = 1, DLG_STATE_EARLY = 2, DLG_STATE_CONFIRMED = 3,
  DLG_STATE_TERMINATED_ONE_SIDE = 4, DLG_STATE_TERMINATED = 5
}
enum  p_dialog_direction { DLG_MOBILE_ORIGINATING = 0, DLG_MOBILE_TERMINATING = 1, DLG_MOBILE_UNKNOWN = 2 }

Functions

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.
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.
int P_is_in_dialog (struct sip_msg *msg, char *str1, char *str2)
 Find out if a message is within a saved dialog.
int P_save_dialog (struct sip_msg *msg, char *str1, char *str2)
 Saves a dialog.
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.
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_422_session_expires (struct sip_msg *msg, char *str1, char *str2)
 Send a 422 Session Interval Too Small.
void dialog_timer (unsigned int ticks, void *param)
 The dialog timer looks for expired dialogs and removes them.


Define Documentation

#define DLG_METHOD_MAX   DLG_METHOD_SUBSCRIBE

The last dialog type.

Definition at line 72 of file dlg_state.h.

Referenced by dialog_timer().


Typedef Documentation

typedef struct _p_dialog p_dialog


Enumeration Type Documentation

enum p_dialog_method

Enumerator:
DLG_METHOD_OTHER 
DLG_METHOD_INVITE 
DLG_METHOD_SUBSCRIBE 

Definition at line 65 of file dlg_state.h.

00065                      {
00066     DLG_METHOD_OTHER=0,
00067     DLG_METHOD_INVITE=1,
00068     DLG_METHOD_SUBSCRIBE=2  
00069 };

enum p_dialog_state

Enumerator:
DLG_STATE_UNKNOWN 
DLG_STATE_INITIAL 
DLG_STATE_EARLY 
DLG_STATE_CONFIRMED 
DLG_STATE_TERMINATED_ONE_SIDE 
DLG_STATE_TERMINATED 

Definition at line 74 of file dlg_state.h.

enum p_dialog_direction

Enumerator:
DLG_MOBILE_ORIGINATING 
DLG_MOBILE_TERMINATING 
DLG_MOBILE_UNKNOWN 

Definition at line 83 of file dlg_state.h.

00083                         {
00084     DLG_MOBILE_ORIGINATING=0,
00085     DLG_MOBILE_TERMINATING=1,
00086     DLG_MOBILE_UNKNOWN=2
00087 };


Function Documentation

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 - index of the slot to lock

Definition at line 198 of file dlg_state.c.

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 - index of the slot to unlock

Definition at line 209 of file dlg_state.c.

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

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                     d->call_id.len,d->call_id.s,
00574                     d->transport,d->host.len,d->host.s,d->port);
00575                 LOG(log_level,"INF:"M_NAME":\t\tMethod:["ANSI_MAGENTA"%d"ANSI_GREEN
00576                     "] State:["ANSI_MAGENTA"%d"ANSI_GREEN
00577                     "] Exp:["ANSI_MAGENTA"%4d"ANSI_GREEN"]\n",
00578                     d->method,d->state,
00579                     (int)(d->expires - d_time_now));    
00580                 for(j=0;j<d->routes_cnt;j++)
00581                     LOG(log_level,"INF:"M_NAME":\t\t RR: <"ANSI_YELLOW"%.*s"ANSI_GREEN">\n",            
00582                         d->routes[j].len,d->routes[j].s);                   
00583                 d = d->next;
00584             }       
00585         d_unlock(i);
00586     }
00587     LOG(log_level,"INF:"M_NAME":----------  P-CSCF Dialog List end   --------------\n");    
00588 }

int P_is_in_dialog ( struct sip_msg *  msg,
char *  str1,
char *  str2 
)

Find out if a message is within a saved dialog.

Parameters:
msg - the SIP message
str1 - the direction of the dialog ("orig"/"term")
str2 - not used
Returns:
CSCF_RETURN_TRUE if in, CSCF_RETURN_FALSE else or CSCF_RETURN_BREAK on error

Definition at line 652 of file dlg_state.c.

References cscf_get_call_id(), CSCF_RETURN_BREAK, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, find_dialog_contact(), get_dialog_direction(), is_p_dialog(), and M_NAME.

00653 {
00654     str call_id;
00655     str host;
00656     int port,transport;
00657     enum p_dialog_direction dir;
00658 
00659     dir = get_dialog_direction(str1);
00660     
00661     if (!find_dialog_contact(msg,dir,&host,&port,&transport)){
00662         LOG(L_ERR,"ERR:"M_NAME":P_is_in_dialog(%s): Error retrieving %s contact\n",str1,str1);
00663         return CSCF_RETURN_BREAK;
00664     }       
00665 
00666     //print_p_dialog(L_ERR);
00667     call_id = cscf_get_call_id(msg,0);
00668     if (!call_id.len)
00669         return CSCF_RETURN_FALSE;
00670             
00671     if (is_p_dialog(call_id,host,port,transport,0)) {
00672         return CSCF_RETURN_TRUE;
00673     }
00674     else 
00675         return CSCF_RETURN_FALSE;
00676 }

int P_save_dialog ( struct sip_msg *  msg,
char *  str1,
char *  str2 
)

Saves a dialog.

Parameters:
msg - the initial request
str1 - direction - "orig" or "term"
str2 - not used
Returns:
CSCF_RETURN_TRUE if ok, CSCF_RETURN_FALSE if not or CSCF_RETURN_BREAK on error

Definition at line 825 of file dlg_state.c.

References add_p_dialog(), cscf_get_call_id(), cscf_get_cseq(), cscf_get_from_tag(), cscf_get_from_uri(), cscf_get_session_expires(), cscf_get_session_expires_body(), cscf_get_to_uri(), CSCF_RETURN_BREAK, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, d_act_time(), d_unlock(), del_p_dialog(), _p_dialog::dialog_c, _p_dialog::dialog_s, _p_dialog::direction, DLG_STATE_INITIAL, _p_dialog::expires, find_dialog_contact(), _p_dialog::first_cseq, get_dialog_direction(), get_dialog_method(), _p_dialog::hash, is_p_dialog(), _p_dialog::last_cseq, _p_dialog::lr_session_expires, M_NAME, _p_dialog::method, _p_dialog::method_str, print_p_dialogs(), _p_dialog::refresher, _p_dialog::state, STR_SHM_DUP, supports_extension(), tmb, and _p_dialog::uac_supp_timer.

00826 {
00827     str call_id;
00828     p_dialog *d;
00829     str host;
00830     time_t t_time;
00831     str ses_exp = {0,0};
00832     str refresher = {0,0};
00833     int port,transport;
00834     char buf1[256],buf2[256];
00835     str tag,ruri,uri,x;
00836     struct hdr_field *h;
00837     unsigned int hash;
00838     enum p_dialog_direction dir;
00839     
00840     dir = get_dialog_direction(str1);
00841     
00842     if (!find_dialog_contact(msg,dir,&host,&port,&transport)){
00843         LOG(L_ERR,"ERR:"M_NAME":P_is_in_dialog(): Error retrieving %s contact\n",str1);
00844         return CSCF_RETURN_BREAK;
00845     }       
00846         
00847     call_id = cscf_get_call_id(msg,0);
00848     if (!call_id.len)
00849         return CSCF_RETURN_FALSE;
00850 
00851     LOG(L_DBG,"DBG:"M_NAME":P_save_dialog(%s): Call-ID <%.*s>\n",str1,call_id.len,call_id.s);
00852 
00853     if (is_p_dialog(call_id,host,port,transport,&dir)){
00854         LOG(L_ERR,"ERR:"M_NAME":P_save_dialog: dialog already exists!\n");  
00855         return CSCF_RETURN_TRUE;
00856     }
00857     
00858     d = add_p_dialog(call_id,host,port,transport);
00859     if (!d) return CSCF_RETURN_FALSE;
00860 
00861     d->method = get_dialog_method(msg->first_line.u.request.method);
00862     STR_SHM_DUP(d->method_str,msg->first_line.u.request.method,"shm");
00863     d->first_cseq = cscf_get_cseq(msg,0);
00864     d->last_cseq = d->first_cseq;
00865     d->state = DLG_STATE_INITIAL;
00866 
00867     d->uac_supp_timer = supports_extension(msg, &str_ext_timer);
00868 
00869     ses_exp = cscf_get_session_expires_body(msg, &h);
00870     t_time = cscf_get_session_expires(ses_exp, &refresher);
00871     if (!t_time){
00872         d->expires = d_act_time() + 60;
00873         d->lr_session_expires = 0;
00874     }else {
00875         d->expires = d_act_time() + t_time;
00876         d->lr_session_expires = t_time;
00877         if (refresher.len)
00878             STR_SHM_DUP(d->refresher, refresher, "DIALOG_REFRESHER");
00879     }
00880     
00881     d->direction=dir;
00882                 
00883     cscf_get_from_tag(msg,&tag);
00884     cscf_get_from_uri(msg,&x);
00885     uri.len = snprintf(buf1,256,"<%.*s>",x.len,x.s);
00886     uri.s = buf1;   
00887     cscf_get_to_uri(msg,&x);
00888     ruri.len = snprintf(buf2,256,"<%.*s>",x.len,x.s);
00889     ruri.s = buf2;
00890         
00891     tmb.new_dlg_uac(&call_id,
00892                     &tag,
00893                     d->first_cseq,
00894                     &uri,
00895                     &ruri,
00896                     &d->dialog_c);
00897                     
00898     tmb.new_dlg_uas(msg,99,&d->dialog_s);
00899         
00900