#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 MAX_TIMES_TO_TRY_TO_RELEASE 5 |
Definition at line 65 of file release_call.h.
| 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.
| callid | - the Call-ID to release | |
| reason | - the Reason header to include in messages |
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.
| d | - pointer to the s_dialog structure | |
| reason | - Reason header to include |
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 }
1.5.2