Currently chan_ss7 doesn't give a cow when the caller gets a "no charge" in the backwards call indicator field and sends an answer frame to the calling channel in any case. I made this patch to fix it. It just records the charge indicator received in the ACM response in a field in the pvt struct, and when the ANM arrives, it abstains from forwarding the answer frame if the previously recorded value was 2 (no charge).

I tested it calling an invalid number from a SIP ATA and it works OK. I hear the other phone company's recording as early media and the call is no longer billed. I tested in 0.9, but the patch applies to 1.0.0 too.

This patch is GPL v2 and (C) Instant Solutions Ltda. of Brazil.

Juan Carlos Castro y Castro
Instant Solution Ltda. <http://www.instant.com.br/>
Rio de Janeiro - Brazil
Index: l4isup.c
===================================================================
--- l4isup.c	(revision 5275)
+++ l4isup.c	(working copy)
@@ -109,6 +109,7 @@
   int reset_done;               /* False until circuit has been init reset */
   int hangupcause;
   int has_inband_ind;
+  int charge_indicator;
   /* Circuit blocking status: {local,remote} {maintenance,hardware}. */
   enum { BL_LM=1, BL_LH=2, BL_RM=4, BL_RH=8, BL_UNEQUIPPED=0x10, BL_LINKDOWN=0x20 } blocked;
   /* Circuit equipped */
@@ -2557,6 +2558,8 @@
   }
   t9_start(chan);
 
+  pvt->charge_indicator = inmsg->acm.back_ind.charge_indicator;
+
   /* Q.764 (2.1.4.6 a): Alert if called_party_status is "subscriber free". */
   if(inmsg->acm.back_ind.called_party_status == 1) {
     ast_queue_frame(chan, &ring_frame);
@@ -2569,7 +2572,6 @@
 static void process_anm(struct ss7_chan *pvt, struct isup_msg *inmsg)
 {
   struct ast_channel* chan = pvt->owner;
-  static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
 
   /* Q.764 (2.1.7.6): When receiving ANM, stop T9. */
   t9_clear(pvt);
@@ -2593,9 +2595,14 @@
     zt_enable_ec(pvt);
   }
 
-  ast_queue_frame(chan, &answer_frame);
-  pvt->state = ST_CONNECTED;
-  ast_setstate(chan, AST_STATE_UP);
+  if (pvt->charge_indicator == 1) {
+    ast_log(LOG_DEBUG, "We previously had a \"no charge\" charge indicator at CIC=%d!\n", pvt->cic);
+  } else {
+    static struct ast_frame answer_frame = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER };
+    ast_queue_frame(chan, &answer_frame);
+    pvt->state = ST_CONNECTED;
+    ast_setstate(chan, AST_STATE_UP);
+  }
   check_obci(pvt, inmsg->anm.obc_ind);
 }
 
@@ -3879,6 +3886,7 @@
   pvt->echocan_start = 0;
   pvt->echocancel = 0;
   pvt->has_inband_ind = 0;
+  pvt->charge_indicator = 0;
   pvt->grs_count = -1;
   pvt->cgb_mask = 0;
   memset(pvt->context, 0, sizeof(pvt->context));
Index: isup.c
===================================================================
--- isup.c	(revision 5275)
+++ isup.c	(working copy)
@@ -240,6 +240,7 @@
     return 0;
   }
   ind_ptr->called_party_status = (p[0] >> 2) & 0x3;
+  ind_ptr->charge_indicator = p[0] & 0x3;
   return 1;
 }
 
Index: isup.h
===================================================================
--- isup.h	(revision 5275)
+++ isup.h	(working copy)
@@ -94,6 +94,7 @@
 /* Fields in a "backwards call indicators" parameter (ACM). */
 struct isup_backwards_call_ind {
   int called_party_status;
+  int charge_indicator;
 };
 
 /* Fields in "redirection information" parameter. */
_______________________________________________
--Bandwidth and Colocation Provided by http://www.api-digital.com--

asterisk-ss7 mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/asterisk-ss7

Reply via email to