release_call.h File Reference

#include "../tm/tm_load.h"
#include "../dialog/dlg_mod.h"
#include "dlg_state.h"

Go to the source code of this file.

Defines

#define MAX_TIMES_TO_TRY_TO_RELEASE   5

Functions

int release_call (str call_id, str reason)
 Given a call-id, locate if its terminating,orginating or both release the dialog involved and drop the dialog.
int release_call_s (s_dialog *d, str reason)
 Given an s_dialog, releases the call.
int release_subscription (s_dialog *d)


Define Documentation

#define MAX_TIMES_TO_TRY_TO_RELEASE   5

Definition at line 65 of file release_call.h.


Function Documentation

int release_call ( str  callid,
str  reason 
)

Given a call-id, locate if its terminating,orginating or both release the dialog involved and drop the dialog.

Parameters:
callid - the Call-ID to release
reason - the Reason header to include in messages
Returns:
0 on error, 1 on success

Definition at line 208 of file release_call.c.

References d_unlock(), DLG_MOBILE_ORIGINATING, DLG_MOBILE_TERMINATING, get_s_dialog_dir(), _s_dialog::hash, and release_call_s().

00209 {
00210     s_dialog *d=0;
00211     unsigned int hash;
00212     int res = 0;
00213     
00214     d = get_s_dialog_dir(callid,DLG_MOBILE_ORIGINATING);
00215     if (d) {                
00216         hash = d->hash;
00217         if (release_call_s(d,reason)>0) res = 1;        
00218         goto done;      
00219     }
00220     d = get_s_dialog_dir(callid,DLG_MOBILE_TERMINATING);
00221     if (d) {                
00222         hash = d->hash;
00223         if (release_call_s(d,reason)>0) res = 1;        
00224         goto done;
00225     } 
00226     
00227     /*Neither ORGINATING nor TERMINATING is UNKNOWN!*/
00228     /*or doesn't exist*/
00229     /*drop it silently?*/
00230     /*treat it as ORIGINATING or TERMINATING?*/             
00231 done:       
00232     if (d) d_unlock(hash);
00233     return res; 
00234 }

int release_call_s ( s_dialog d,
str  reason 
)

Given an s_dialog, releases the call.

This function is already called with a lock in d after returning d should be unlocked.

Parameters:
d - pointer to the s_dialog structure
reason - Reason header to include
Returns:
-1 if dialog the dialog is not confirmed, 0 on error or 1 on success

Definition at line 245 of file release_call.c.

References alter_dialog_route_set(), _s_dialog::call_id, confirmed_response(), content_length_s, default_reason_s, _s_dialog::dialog_c, _s_dialog::dialog_s, _s_dialog::direction, DLG_MOBILE_ORIGINATING, DLG_MOBILE_TERMINATING, DLG_STATE_CONFIRMED, get_s_dialog_dir_nolock(), _s_dialog::is_releasing, M_NAME, MAX_TIMES_TO_TRY_TO_RELEASE, method_bye_s, send_request(), _s_dialog::state, and STR_APPEND.

Referenced by release_call(), and terminate_s_dialog().

00246 {
00247     enum s_dialog_direction odir;
00248     s_dialog *o;
00249     str reqbuf={0,0};
00250 
00251     LOG(L_INFO,"DBG:"M_NAME":release_call_s(): Releasing call <%.*s> DIR[%d].\n",
00252         d->call_id.len,d->call_id.s,d->direction);
00253                     
00254     /* As for now, i'm only releasing confirmed dialogs */
00255     if (d->state < DLG_STATE_CONFIRMED){
00256         LOG(L_INFO,"ERR:"M_NAME":release_call_s(): Unable to release a non-confirmed dialog\n");        
00257         return -1;
00258     }
00259         
00260     /* get the dialog in the other direction to see if something going on there and mark as in releasing */
00261     switch (d->direction){
00262         case DLG_MOBILE_ORIGINATING:
00263             odir = DLG_MOBILE_TERMINATING;
00264             break;
00265         case DLG_MOBILE_TERMINATING:
00266             odir = DLG_MOBILE_ORIGINATING;
00267             break;
00268         default:
00269             odir = d->direction;
00270     }   
00271     
00272     o = get_s_dialog_dir_nolock(d->call_id,odir);
00273     if (o && !o->is_releasing) o->is_releasing = 1;
00274         
00275     d->is_releasing++;
00276         
00277     if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE){
00278         LOG(L_ERR,"ERR:"M_NAME":release_call_s(): had to delete silently dialog %.*s in direction %i\n",d->call_id.len,d->call_id.s,d->direction);
00279         
00280         return 0;
00281     }
00282     if (d->is_releasing==1) {   
00283         /*Before generating a request, we have to generate
00284          * the route_set in the dlg , because the route set
00285          * in the dialog is for the UAC everything which was in the 
00286          * Record-Routes (including local address)*/
00287         alter_dialog_route_set(d->dialog_c,d->direction);       
00288         
00289         /*first generate the bye for called user*/
00290         /*then generate the bye for the calling user*/
00291         /*send_bye(d->dialog_c,bye_response,d->direction,reason);
00292         send_bye(d->dialog_s,bye_response,d->direction,reason);*/
00293         
00294         /*now prepare the headers*/
00295         if (reason.len)
00296         {
00297             reqbuf.len = reason.len+content_length_s.len;
00298             reqbuf.s = pkg_malloc(reqbuf.len);
00299             if (!reqbuf.s){
00300                 LOG(L_ERR,"ERR:"M_NAME":release_call_s(): Error allocating %d bytes.\n",
00301                     reqbuf.len);
00302                 return 0;
00303             }       
00304             reqbuf.len=0;
00305             STR_APPEND(reqbuf,reason);
00306             STR_APPEND(reqbuf,content_length_s);
00307             
00308         } else {
00309             reqbuf.len = default_reason_s.len+content_length_s.len;
00310             reqbuf.s = pkg_malloc(reqbuf.len);
00311             if (!reqbuf.s){
00312                 LOG(L_ERR,"ERR:"M_NAME":release_call_s(): Error allocating %d bytes.\n",
00313                     reqbuf.len);
00314                 return 0;
00315             }       
00316             reqbuf.len=0;
00317             STR_APPEND(reqbuf,default_reason_s);
00318             STR_APPEND(reqbuf,content_length_s);
00319         }
00320         
00321         
00322         send_request(method_bye_s,reqbuf,d->dialog_c,confirmed_response,d->direction);
00323         send_request(method_bye_s,reqbuf,d->dialog_s,confirmed_response,d->direction);
00324         
00325         /*the dialog is droped by the callback-function when recieves the two replies */
00326     }
00327     if (reqbuf.s)
00328         pkg_free(reqbuf.s);  
00329     return 1;
00330 }

int release_subscription ( s_dialog d  ) 

Definition at line 342 of file release_call.c.

References alter_dialog_route_set(), _s_dialog::call_id, confirmed_response(), content_length_s, del_s_dialog(), _s_dialog::dialog_c, _s_dialog::dialog_s, _s_dialog::direction, _s_dialog::event, hdr_contact1_s, hdr_contact2_s, hdr_event1_s, hdr_event2_s, hdr_expires_s, hdrs_notify_s, _s_dialog::is_releasing, M_NAME, MAX_TIMES_TO_TRY_TO_RELEASE, method_NOTIFY_s, method_SUBSCRIBE_s, send_request(), and STR_APPEND.

Referenced by terminate_s_dialog().

00343 {
00344     /*i dont think in this case all the checking with the directions is needed
00345      * because the SUBSCRIBE initiated dialog doesnt go twice through the S-CSCF or does it?*/
00346     str reqbuf={0,0};
00347     str c_uri={0,0}; 
00348     d->is_releasing++;
00349     
00350     if (d->is_releasing>MAX_TIMES_TO_TRY_TO_RELEASE)
00351     {
00352         LOG(L_ERR,"ERR:"M_NAME":release_subscription(): had to delete silently a SUBSCRIBE initiated dialog %.*s\n",d->call_id.len,d->call_id.s);
00353         del_s_dialog(d);
00354         return 1;
00355     }
00356     if (d->is_releasing==1)
00357     {
00358         d->dialog_c->state=DLG_CONFIRMED;
00359         alter_dialog_route_set(d->dialog_c,d->direction);
00360         
00361         //SUBSCRIBE
00362         /*Add Contents-Length thing makes everything more complicated*/
00363         c_uri = d->dialog_s->rem_target;
00364         reqbuf.len = hdr_expires_s.len+content_length_s.len;
00365         if (d->event.len) 
00366             reqbuf.len+=hdr_event1_s.len+d->event.len+hdr_event2_s.len;         
00367         if (c_uri.len) 
00368             reqbuf.len+=hdr_contact1_s.len+c_uri.len+hdr_contact2_s.len;            
00369         reqbuf.s=pkg_malloc(reqbuf.len);
00370         if (!reqbuf.s){
00371             LOG(L_ERR,"ERR:"M_NAME":release_subscription(): Error allocating %d bytes.\n",
00372                 reqbuf.len);
00373             return 0;
00374         }
00375         reqbuf.len=0;
00376         STR_APPEND(reqbuf,hdr_expires_s);
00377         if (d->event.len){
00378             STR_APPEND(reqbuf,hdr_event1_s);
00379             STR_APPEND(reqbuf,d->event);            
00380             STR_APPEND(reqbuf,hdr_event2_s);
00381         }
00382         if (c_uri.len){
00383             STR_APPEND(reqbuf,hdr_contact1_s);
00384             STR_APPEND(reqbuf,c_uri);           
00385             STR_APPEND(reqbuf,hdr_contact2_s);
00386         }
00387         STR_APPEND(reqbuf,content_length_s);
00388         
00389         send_request(method_SUBSCRIBE_s,reqbuf,d->dialog_c,confirmed_response,d->direction);
00390         if (reqbuf.s)
00391             pkg_free(reqbuf.s);
00392         
00393         //NOTIFY    
00394         /*Now add the Contents-Length thing for the NOTIFY*/
00395         c_uri = d->dialog_c->rem_target;
00396         reqbuf.len = hdrs_notify_s.len+content_length_s.len;
00397         if (d->event.len) 
00398             reqbuf.len+=hdr_event1_s.len+d->event.len+hdr_event2_s.len;
00399         if (c_uri.len) 
00400             reqbuf.len+=hdr_contact1_s.len+c_uri.len+hdr_contact2_s.len;            
00401         reqbuf.s = pkg_malloc(reqbuf.len);
00402         if (!reqbuf.s){
00403             LOG(L_ERR,"ERR:"M_NAME":release_subscription(): Error allocating %d bytes.\n",
00404                 reqbuf.len);
00405             return 0;
00406         }       
00407         reqbuf.len=0;
00408         STR_APPEND(reqbuf,hdrs_notify_s);
00409         if (d->event.len){
00410             STR_APPEND(reqbuf,hdr_event1_s);
00411             STR_APPEND(reqbuf,d->event);            
00412             STR_APPEND(reqbuf,hdr_event2_s);
00413         }
00414         if (c_uri.len){
00415             STR_APPEND(reqbuf,hdr_contact1_s);
00416             STR_APPEND(reqbuf,c_uri);           
00417             STR_APPEND(reqbuf,hdr_contact2_s);
00418         }   
00419         STR_APPEND(reqbuf,content_length_s);
00420         
00421         send_request(method_NOTIFY_s,reqbuf,d->dialog_s,confirmed_response,d->direction);
00422         if (reqbuf.s)
00423             pkg_free(reqbuf.s);
00424     }
00425     return 1;
00426 }


Generated on Thu Oct 23 04:14:45 2008 for Open IMS Core CSCFs by  doxygen 1.5.2