Browse code

added sems specific patch. This patch is present in the ser version shipped on iptel.org/drupal/sems.

Raphael Coeffic authored on 12/06/2006 08:22:48
Showing 7 changed files
... ...
@@ -43,16 +43,17 @@ struct sip_msg;
43 43
 struct cell;
44 44
 
45 45
 
46
-#define TMCB_REQUEST_IN       (1<<0)
47
-#define TMCB_RESPONSE_IN      (1<<1)
48
-#define TMCB_E2EACK_IN        (1<<2)
49
-#define TMCB_REQUEST_FWDED    (1<<3)
50
-#define TMCB_RESPONSE_FWDED   (1<<4)
51
-#define TMCB_ON_FAILURE_RO    (1<<5)
52
-#define TMCB_ON_FAILURE       (1<<6)
53
-#define TMCB_RESPONSE_OUT     (1<<7)
54
-#define TMCB_LOCAL_COMPLETED  (1<<8)
55
-#define TMCB_MAX              ((1<<9)-1)
46
+#define TMCB_REQUEST_IN         (1<<0)
47
+#define TMCB_RESPONSE_IN        (1<<1)
48
+#define TMCB_E2EACK_IN          (1<<2)
49
+#define TMCB_REQUEST_FWDED      (1<<3)
50
+#define TMCB_RESPONSE_FWDED     (1<<4)
51
+#define TMCB_ON_FAILURE_RO      (1<<5)
52
+#define TMCB_ON_FAILURE         (1<<6)
53
+#define TMCB_RESPONSE_OUT       (1<<7)
54
+#define TMCB_LOCAL_COMPLETED    (1<<8)
55
+#define TMCB_LOCAL_RESPONSE_OUT (1<<9)
56
+#define TMCB_MAX                ((1<<10)-1)
56 57
 
57 58
 /* 
58 59
  *  Caution: most of the callbacks work with shmem-ized messages
... ...
@@ -98,6 +98,7 @@
98 98
 #include "t_fwd.h"
99 99
 #include "fix_lumps.h"
100 100
 #include "t_stats.h"
101
+#include "uac.h"
101 102
 
102 103
 
103 104
 /* restart fr timer on each provisional reply, default yes */
... ...
@@ -1204,6 +1205,15 @@ enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
1204 1205
 		}
1205 1206
 	}
1206 1207
 	UNLOCK_REPLIES(t);
1208
+ 
1209
+        if (local_winner >= 0 && pass_provisional_replies && winning_code < 200) {
1210
+                if (!totag_retr && has_tran_tmcbs(t, TMCB_LOCAL_RESPONSE_OUT) ) {
1211
+                        DBG("DEBUG: Passing provisional reply %d to FIFO application\n", winning_code);
1212
+                        run_trans_callbacks( TMCB_LOCAL_RESPONSE_OUT, t, 0,
1213
+                                winning_msg, winning_code);
1214
+                }
1215
+        }
1216
+ 
1207 1217
 	if (local_winner>=0 && winning_code>=200 ) {
1208 1218
 		DBG("DEBUG: local transaction completed\n");
1209 1219
 		if (!totag_retr) {
... ...
@@ -274,6 +274,7 @@ static param_export_t params[]={
274 274
 	{"fr_timer_avp",        STR_PARAM, &fr_timer_param                       },
275 275
 	{"fr_inv_timer_avp",    STR_PARAM, &fr_inv_timer_param                   },
276 276
 	{"tw_append",           STR_PARAM|USE_FUNC_PARAM, (void*)parse_tw_append },
277
+        {"pass_provisional_replies", INT_PARAM, &pass_provisional_replies        },
277 278
 	{0,0,0}
278 279
 };
279 280
 
... ...
@@ -75,6 +75,8 @@ static char from_tag[FROM_TAG_LEN + 1];
75 75
 
76 76
 char* uac_from = "sip:foo@foo.bar"; /* Module parameter */
77 77
 
78
+/* Enable/disable passing of provisional replies to FIFO applications */
79
+int pass_provisional_replies = 0;
78 80
 
79 81
 /*
80 82
  * Initialize UAC
... ...
@@ -164,15 +166,14 @@ static inline unsigned int dlg2hash( dlg_t* dlg )
164 166
  * Send a request using data from the dialog structure
165 167
  */
166 168
 int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
167
-												transaction_cb cb, void* cbp)
169
+	  transaction_cb cb, void* cbp)
168 170
 {
169 171
 	struct socket_info* send_sock;
170 172
 	union sockaddr_union to_su;
171 173
 	struct cell *new_cell;
172 174
 	struct retr_buf *request;
173 175
 	char* buf;
174
-	int buf_len;
175
-	int ret;
176
+        int buf_len, ret, flags;
176 177
 	unsigned int hi;
177 178
 
178 179
 	ret=-1;
... ...
@@ -205,8 +206,13 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
205 206
 	reset_avps();
206 207
 
207 208
 	/* add the callback the the transaction for LOCAL_COMPLETED event */
208
-	if(cb && insert_tmcb(&(new_cell->tmcb_hl),TMCB_LOCAL_COMPLETED,cb,cbp)!=1){
209
-		ret=E_OUT_OF_MEM;
209
+ 
210
+        flags = TMCB_LOCAL_COMPLETED;
211
+             /* Add also TMCB_LOCAL_REPLY_OUT if provisional replies are desired */
212
+        if (pass_provisional_replies) flags |= TMCB_LOCAL_RESPONSE_OUT;
213
+ 
214
+        if(cb && insert_tmcb(&(new_cell->tmcb_hl), flags, cb, cbp)!=1){
215
+                ret=E_OUT_OF_MEM; 
210 216
 		LOG(L_ERR, "t_uac: short of tmcb shmem\n");
211 217
 		goto error2;
212 218
 	}
... ...
@@ -41,7 +41,7 @@
41 41
 #define DEFAULT_CSEQ 10 /* Default CSeq number */
42 42
 
43 43
 extern char *uac_from;  /* UAC From parameter */
44
-
44
+extern int pass_provisional_replies; /* Pass provisional replies to fifo applications */
45 45
 
46 46
 /*
47 47
  * Function prototypes
... ...
@@ -570,7 +570,10 @@ static void fifo_callback( struct cell *t, int type, struct tmcb_params *ps )
570 570
 	}
571 571
 	DBG("DEBUG: fifo_callback successfully completed\n");
572 572
 done:
573
-	shm_free(filename);
573
+        if (ps->code >= 200) {
574
+	        /* Do not free if we received provisional reply */
575
+                shm_free(filename);
576
+        }
574 577
 }
575 578
 
576 579
 
... ...
@@ -50,6 +50,13 @@ struct str_list {
50 50
 	struct str_list *next;
51 51
 };
52 52
 
53
+struct uac_cb_param {
54
+    
55
+    str from;
56
+    str callid;
57
+    str cseq;
58
+    struct sockaddr_un addr;
59
+};
53 60
 
54 61
 #define skip_hf(_hf) (             \
55 62
     ((_hf)->type == HDR_FROM)   || \
... ...
@@ -426,10 +433,67 @@ static int print_uris(struct sip_msg* reply)
426 433
 	return 0;
427 434
 }
428 435
 
436
+static int new_uac_cb_param(struct uac_cb_param** param,
437
+			    struct sip_msg* msg, 
438
+			    struct sockaddr_un* addr)
439
+{
440
+    int len=0;
441
+    struct uac_cb_param* p_param=0;
442
+
443
+    if(msg && addr) {
444
+
445
+	*param = shm_malloc(sizeof(struct uac_cb_param));
446
+	if (!*param) {
447
+	    unixsock_reply_asciiz("500 No shared memory");
448
+	    return -1;
449
+	}
450
+	
451
+	p_param = *param;
452
+
453
+	len += msg->from->len;
454
+	len += msg->callid->len;
455
+	len += msg->cseq->len;
456
+
457
+	p_param->from.s = shm_malloc(len);
458
+	if(!p_param->from.s){
459
+
460
+	    shm_free(p_param);
461
+	    *param = 0;
462
+
463
+	    unixsock_reply_asciiz("500 No shared memory");
464
+	    return -1;
465
+	}
466
+
467
+	memcpy(p_param->from.s,msg->from->name.s,msg->from->len);
468
+	p_param->from.len = msg->from->len;
469
+
470
+	p_param->callid.s = p_param->from.s + p_param->from.len;
471
+	memcpy(p_param->callid.s,msg->callid->name.s,msg->callid->len);
472
+	p_param->callid.len = msg->callid->len;
473
+
474
+	p_param->cseq.s = p_param->callid.s + p_param->callid.len;
475
+	memcpy(p_param->cseq.s,msg->cseq->name.s,msg->cseq->len);
476
+	p_param->cseq.len = msg->cseq->len;
477
+
478
+	memcpy(&(p_param->addr), addr, sizeof(struct sockaddr_un));
479
+
480
+    } else {
481
+	*param = 0;
482
+    }
483
+    return 0;
484
+}
485
+
486
+static void free_uac_cb_param(struct uac_cb_param* param)
487
+{
488
+    shm_free(param->from.s);
489
+    shm_free(param);
490
+}
429 491
 
430 492
 static void callback(struct cell *t, int type, struct tmcb_params *ps)
431 493
 {
432
-	struct sockaddr_un* to;
494
+	struct sockaddr_un*  to;
495
+	struct uac_cb_param* param=0;
496
+
433 497
 	str text;
434 498
 
435 499
 	if (!*ps->param) {
... ...
@@ -437,7 +501,8 @@ static void callback(struct cell *t, int type, struct tmcb_params *ps)
437 501
 		return;
438 502
 	}
439 503
 	
440
-	to = (struct sockaddr_un*)(*ps->param);
504
+	param = (struct uac_cb_param*)(*ps->param);
505
+	to = &param->addr;
441 506
 	unixsock_reply_reset();
442 507
 
443 508
 	if (ps->rpl == FAKED_REPLY) {
... ...
@@ -447,8 +512,15 @@ static void callback(struct cell *t, int type, struct tmcb_params *ps)
447 512
 			unixsock_reply_asciiz("500 callback: get_reply_status failed\n");
448 513
 			goto done;
449 514
 		}
450
-		unixsock_reply_printf("%.*s\n", text.len, text.s);
515
+
516
+		unixsock_reply_printf("%.*s\n.\n.\n.\n", text.len, text.s);
517
+
518
+		unixsock_reply_printf("%.*s", param->from.len, param->from.s);
519
+		unixsock_reply_printf("%.*s", param->callid.len, param->callid.s);
520
+		unixsock_reply_printf("%.*s\n", param->cseq.len, param->cseq.s);
521
+
451 522
 		pkg_free(text.s);
523
+
452 524
 	} else {
453 525
 		text.s = ps->rpl->first_line.u.reply.reason.s;
454 526
 		text.len = ps->rpl->first_line.u.reply.reason.len;
... ...
@@ -460,15 +532,20 @@ static void callback(struct cell *t, int type, struct tmcb_params *ps)
460 532
 	}
461 533
 done:
462 534
 	unixsock_reply_sendto(to);
463
-	shm_free(to);
464
-	*ps->param=0; /* 0 it so the callback won't do anything if called
465
-					 for a retransmission */
535
+
536
+        if (ps->code >= 200) {
537
+
538
+	    free_uac_cb_param(param);
539
+	    *ps->param=0; /* 0 it so the callback won't do 
540
+			     anything if called for a retransmission */
541
+	}
466 542
 }
467 543
 
468 544
 
469 545
 /*
470 546
  * Create shm_copy of filename
471 547
  */
548
+/*
472 549
 static int duplicate_addr(struct sockaddr_un** dest, struct sockaddr_un* addr)
473 550
 {
474 551
 	if (addr) {
... ...
@@ -483,7 +560,7 @@ static int duplicate_addr(struct sockaddr_un** dest, struct sockaddr_un* addr)
483 560
 	}
484 561
 	return 0;
485 562
 }
486
-
563
+*/
487 564
 
488 565
 int unixsock_uac(str* msg)
489 566
 {
... ...
@@ -492,7 +569,8 @@ int unixsock_uac(str* msg)
492 569
 	struct sip_msg faked_msg;
493 570
 	int ret, sip_error, err_ret, fromtag, cseq_is, cseq;
494 571
 	char err_buf[MAX_REASON_LEN];
495
-	struct sockaddr_un* shm_sockaddr;
572
+	/*struct sockaddr_un* shm_sockaddr;*/
573
+	struct uac_cb_param* shm_param;
496 574
 	dlg_t dlg;
497 575
 
498 576
 	if (get_method(&method, msg) < 0) return -1;
... ...
@@ -551,10 +629,14 @@ int unixsock_uac(str* msg)
551 629
 	dlg.hooks.request_uri = &ruri;
552 630
 	dlg.hooks.next_hop = (nexthop.len ? &nexthop : &ruri);
553 631
 	
554
-	     /* we got it all, initiate transaction now! */
555
-	if (duplicate_addr(&shm_sockaddr, unixsock_sender_addr()) < 0) goto error01;
632
+	if (new_uac_cb_param(&shm_param,&faked_msg,unixsock_sender_addr()) < 0) {
633
+	    
634
+	    unixsock_reply_send();
635
+	    goto error01;
636
+	}
556 637
 
557
-	ret = t_uac(&method, &hfb, &body, &dlg, callback, shm_sockaddr);
638
+	     /* we got it all, initiate transaction now! */
639
+	ret = t_uac(&method, &hfb, &body, &dlg, callback, shm_param);
558 640
 	if (ret <= 0) {
559 641
 		err_ret = err2reason_phrase(ret, &sip_error, err_buf, sizeof(err_buf), "FIFO/UAC");
560 642
 		if (err_ret > 0) {
... ...
@@ -563,7 +645,7 @@ int unixsock_uac(str* msg)
563 645
 			unixsock_reply_asciiz("500 UNIXSOCK/UAC error");
564 646
 		}
565 647
 		unixsock_reply_send();
566
-		shm_free(shm_sockaddr);
648
+		free_uac_cb_param(shm_param);
567 649
 		goto error01;
568 650
 	}
569 651