@@ -207,7 +207,8 @@ static struct b2b_sdp_stream *b2b_sdp_stream_raw_new(struct b2b_sdp_client *clie
207
207
#define B2B_SDP_CLIENT_EARLY (1<<0)
208
208
#define B2B_SDP_CLIENT_STARTED (1<<1)
209
209
#define B2B_SDP_CLIENT_PENDING (1<<2)
210
- #define B2B_SDP_CLIENT_REPL (1<<3)
210
+ #define B2B_SDP_CLIENT_REPL (1<<3)
211
+ #define B2B_SDP_CLIENT_CANCEL (1<<4)
211
212
212
213
struct b2b_sdp_client {
213
214
unsigned int flags ;
@@ -393,27 +394,17 @@ static struct b2b_sdp_client *b2b_sdp_client_new(struct b2b_sdp_ctx *ctx)
393
394
return client ;
394
395
}
395
396
396
- static void b2b_sdp_client_terminate (struct b2b_sdp_client * client , str * key )
397
+ static void b2b_sdp_client_end (struct b2b_sdp_client * client , str * key , int send_cancel )
397
398
{
398
399
str method ;
399
400
b2b_req_data_t req_data ;
400
- int send_cancel = 0 ;
401
- if (!key || key -> len == 0 ) {
402
- LM_WARN ("cannot terminate non-started client\n" );
403
- return ;
404
- }
405
- lock_get (& client -> ctx -> lock );
406
- send_cancel = (client -> flags & B2B_SDP_CLIENT_EARLY );
407
- if (!send_cancel && !(client -> flags & B2B_SDP_CLIENT_STARTED )) {
408
- lock_release (& client -> ctx -> lock );
409
- goto delete ;
410
- }
411
- client -> flags &= ~(B2B_SDP_CLIENT_EARLY |B2B_SDP_CLIENT_STARTED );
412
- lock_release (& client -> ctx -> lock );
413
- if (send_cancel )
401
+
402
+ if (send_cancel ) {
414
403
init_str (& method , CANCEL );
415
- else
404
+ client -> flags |= B2B_SDP_CLIENT_CANCEL ;
405
+ } else {
416
406
init_str (& method , BYE );
407
+ }
417
408
418
409
memset (& req_data , 0 , sizeof (b2b_req_data_t ));
419
410
req_data .no_cb = 1 ; /* do not call callback */
@@ -425,8 +416,26 @@ static void b2b_sdp_client_terminate(struct b2b_sdp_client *client, str *key)
425
416
LM_INFO ("[%.*s][%.*s] client request %.*s sent\n" ,
426
417
client -> ctx -> callid .len , client -> ctx -> callid .s ,
427
418
key -> len , key -> s , method .len , method .s );
428
- delete :
429
- b2b_api .entity_delete (B2B_CLIENT , key , client -> dlginfo , 1 , 1 );
419
+ }
420
+
421
+ static void b2b_sdp_client_terminate (struct b2b_sdp_client * client , str * key )
422
+ {
423
+ int send_cancel = 0 ;
424
+ if (!key || key -> len == 0 ) {
425
+ LM_WARN ("cannot terminate non-started client\n" );
426
+ return ;
427
+ }
428
+ lock_get (& client -> ctx -> lock );
429
+ send_cancel = (client -> flags & B2B_SDP_CLIENT_EARLY );
430
+ b2b_sdp_client_end (client , key , send_cancel );
431
+ if (!send_cancel && !(client -> flags & B2B_SDP_CLIENT_STARTED )) {
432
+ lock_release (& client -> ctx -> lock );
433
+ return ;
434
+ }
435
+ client -> flags &= ~(B2B_SDP_CLIENT_EARLY |B2B_SDP_CLIENT_STARTED );
436
+ lock_release (& client -> ctx -> lock );
437
+ if (!send_cancel )
438
+ b2b_api .entity_delete (B2B_CLIENT , key , client -> dlginfo , 1 , 1 );
430
439
}
431
440
432
441
static void b2b_sdp_client_free (void * param )
@@ -866,6 +875,11 @@ static int b2b_sdp_client_reinvite(struct sip_msg *msg, struct b2b_sdp_client *c
866
875
}
867
876
lock_get (& client -> ctx -> lock );
868
877
if (client -> flags & B2B_SDP_CLIENT_PENDING ) {
878
+ if ((client -> flags & B2B_SDP_CLIENT_CANCEL ) ||
879
+ (client -> ctx -> flags & B2B_SDP_CTX_CANCELLED )) {
880
+ LM_INFO ("call already cancelled!\n" );
881
+ goto end ;
882
+ }
869
883
LM_INFO ("we still have pending requests!\n" );
870
884
code = 491 ;
871
885
goto end ;
@@ -929,6 +943,14 @@ static void b2b_sdp_client_release_streams(struct b2b_sdp_client *client)
929
943
}
930
944
}
931
945
946
+ static void b2b_sdp_client_destroy (struct b2b_sdp_client * client )
947
+ {
948
+ b2b_sdp_client_release_streams (client );
949
+ b2b_sdp_client_release (client , 0 );
950
+ b2b_api .entity_delete (B2B_CLIENT , & client -> b2b_key , client -> dlginfo , 1 , 1 );
951
+ }
952
+
953
+
932
954
static void b2b_sdp_client_remove (struct b2b_sdp_client * client )
933
955
{
934
956
struct b2b_sdp_ctx * ctx = client -> ctx ;
@@ -1216,6 +1238,13 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien
1216
1238
client -> flags &= ~(B2B_SDP_CLIENT_EARLY |B2B_SDP_CLIENT_PENDING );
1217
1239
1218
1240
if (msg != FAKED_REPLY && msg -> REPLY_STATUS < 300 ) {
1241
+ if (ctx -> flags & B2B_SDP_CTX_CANCELLED ) {
1242
+ LM_DBG ("contex already CANCELLED!\n" );
1243
+ if (!(client -> flags & B2B_SDP_CLIENT_CANCEL ))
1244
+ b2b_sdp_client_end (client , & client -> b2b_key , 0 );
1245
+ b2b_sdp_client_destroy (client );
1246
+ goto release ;
1247
+ }
1219
1248
body = get_body_part (msg , TYPE_APPLICATION , SUBTYPE_SDP );
1220
1249
if (body && b2b_sdp_client_sync (client , body ) >= 0 ) {
1221
1250
ctx -> success_no ++ ;
@@ -1226,9 +1255,7 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien
1226
1255
} else {
1227
1256
if (!(client -> flags & B2B_SDP_CLIENT_STARTED )) {
1228
1257
/* client was not started, thus this is a final negative reply */
1229
- b2b_sdp_client_release_streams (client );
1230
- b2b_sdp_client_release (client , 0 );
1231
- b2b_api .entity_delete (B2B_CLIENT , & client -> b2b_key , client -> dlginfo , 1 , 1 );
1258
+ b2b_sdp_client_destroy (client );
1232
1259
}
1233
1260
}
1234
1261
body = NULL ;
@@ -1255,6 +1282,7 @@ static int b2b_sdp_client_reply_invite(struct sip_msg *msg, struct b2b_sdp_clien
1255
1282
if (b2b_sdp_reply (& ctx -> b2b_key , ctx -> dlginfo , B2B_SERVER , METHOD_INVITE , 200 , body ) < 0 )
1256
1283
LM_CRIT ("could not answer B2B call!\n" );
1257
1284
pkg_free (body -> s );
1285
+ ret = 1 ;
1258
1286
} else if (ret == -2 ) {
1259
1287
b2b_sdp_reply (& ctx -> b2b_key , ctx -> dlginfo , B2B_SERVER , METHOD_INVITE , 503 , NULL );
1260
1288
}
@@ -1539,10 +1567,23 @@ static int b2b_sdp_server_invite(struct sip_msg *msg, struct b2b_sdp_ctx *ctx)
1539
1567
1540
1568
static int b2b_sdp_server_cancel (struct sip_msg * msg , struct b2b_sdp_ctx * ctx )
1541
1569
{
1570
+ int send_cancel ;
1571
+ struct list_head * it ;
1572
+ struct b2b_sdp_client * client ;
1573
+
1542
1574
/* respond to the initial INVITE */
1543
1575
b2b_sdp_reply (& ctx -> b2b_key , ctx -> dlginfo , B2B_SERVER ,
1544
1576
METHOD_INVITE , 487 , NULL );
1545
- b2b_sdp_ctx_release (ctx , 0 );
1577
+ /* we need to cancel each pending client */
1578
+ lock_get (& ctx -> lock );
1579
+ list_for_each (it , & ctx -> clients ) {
1580
+ client = list_entry (it , struct b2b_sdp_client , list );
1581
+ if (!client -> b2b_key .len )
1582
+ continue ;
1583
+ send_cancel = (client -> flags & B2B_SDP_CLIENT_EARLY );
1584
+ b2b_sdp_client_end (client , & client -> b2b_key , send_cancel );
1585
+ }
1586
+ lock_release (& ctx -> lock );
1546
1587
return 0 ;
1547
1588
}
1548
1589
0 commit comments