[asterisk-commits] dvossel: branch dvossel/generic_aoc r256980 - in /team/dvossel/generic_aoc: a...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Apr 12 15:13:19 CDT 2010


Author: dvossel
Date: Mon Apr 12 15:13:12 2010
New Revision: 256980

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=256980
Log:
AOC-S passthrough on call setup support in app_dial, and app_queue, addition of 'aoc_enable' option in dahdi conf

Modified:
    team/dvossel/generic_aoc/apps/app_dial.c
    team/dvossel/generic_aoc/apps/app_queue.c
    team/dvossel/generic_aoc/channels/chan_dahdi.c
    team/dvossel/generic_aoc/channels/sig_pri.c
    team/dvossel/generic_aoc/channels/sig_pri.h
    team/dvossel/generic_aoc/configs/chan_dahdi.conf.sample

Modified: team/dvossel/generic_aoc/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/apps/app_dial.c?view=diff&rev=256980&r1=256979&r2=256980
==============================================================================
--- team/dvossel/generic_aoc/apps/app_dial.c (original)
+++ team/dvossel/generic_aoc/apps/app_dial.c Mon Apr 12 15:13:12 2010
@@ -62,6 +62,7 @@
 #include "asterisk/global_datastores.h"
 #include "asterisk/dsp.h"
 #include "asterisk/cel.h"
+#include "asterisk/aoc.h"
 #include "asterisk/ccss.h"
 #include "asterisk/indications.h"
 
@@ -610,6 +611,7 @@
 	struct ast_channel *chan;
 	uint64_t flags;
 	struct ast_party_connected_line connected;
+	struct ast_aoc_decoded *aoc_s_rate_list;
 };
 
 static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
@@ -617,6 +619,7 @@
 static void chanlist_free(struct chanlist *outgoing)
 {
 	ast_party_connected_line_free(&outgoing->connected);
+	ast_aoc_destroy_decoded(outgoing->aoc_s_rate_list);
 	ast_free(outgoing);
 }
 
@@ -1013,6 +1016,14 @@
 							ast_party_connected_line_free(&connected_caller);
 						}
 					}
+					if (o->aoc_s_rate_list) {
+						size_t encoded_size;
+						struct ast_aoc_encoded *encoded;
+						if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size))) {
+							ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
+							ast_aoc_destroy_encoded(encoded);
+						}
+					}
 					peer = c;
 					ast_copy_flags64(peerflags, o,
 						OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
@@ -1073,6 +1084,14 @@
 								connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
 								ast_channel_update_connected_line(in, &connected_caller);
 								ast_party_connected_line_free(&connected_caller);
+							}
+						}
+						if (o->aoc_s_rate_list) {
+							size_t encoded_size;
+							struct ast_aoc_encoded *encoded;
+							if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size))) {
+								ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
+								ast_aoc_destroy_encoded(encoded);
 							}
 						}
 						peer = c;
@@ -1189,6 +1208,17 @@
 						}
 					}
 					break;
+				case AST_CONTROL_AOC:
+					{
+						struct ast_aoc_decoded *decoded = ast_aoc_decode(f->data.ptr, f->datalen);
+						if (decoded && (ast_aoc_get_msg_type(decoded) == AST_AOC_S)) {
+							ast_aoc_destroy_decoded(o->aoc_s_rate_list);
+							o->aoc_s_rate_list = decoded;
+						} else {
+							ast_aoc_destroy_decoded(decoded);
+						}
+					}
+					break;
 				case AST_CONTROL_REDIRECTING:
 					if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
 						ast_verb(3, "Redirecting update to %s prevented.\n", in->name);

Modified: team/dvossel/generic_aoc/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/apps/app_queue.c?view=diff&rev=256980&r1=256979&r2=256980
==============================================================================
--- team/dvossel/generic_aoc/apps/app_queue.c (original)
+++ team/dvossel/generic_aoc/apps/app_queue.c Mon Apr 12 15:13:12 2010
@@ -94,6 +94,7 @@
 #include "asterisk/strings.h"
 #include "asterisk/global_datastores.h"
 #include "asterisk/taskprocessor.h"
+#include "asterisk/aoc.h"
 #include "asterisk/callerid.h"
 #include "asterisk/cel.h"
 
@@ -799,6 +800,7 @@
 	struct member *member;
 	unsigned int update_connectedline:1;
 	struct ast_party_connected_line connected;
+	struct ast_aoc_decoded *aoc_s_rate_list;
 };
 
 
@@ -2592,6 +2594,7 @@
 		outgoing = outgoing->q_next;
 		if (oo->member)
 			ao2_ref(oo->member, -1);
+		ast_aoc_destroy_decoded(oo->aoc_s_rate_list);
 		ast_free(oo);
 	}
 }
@@ -3256,6 +3259,14 @@
 							connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
 							ast_channel_update_connected_line(in, &connected_caller);
 							ast_party_connected_line_free(&connected_caller);
+						}
+					}
+					if (o->aoc_s_rate_list) {
+						size_t encoded_size;
+						struct ast_aoc_encoded *encoded;
+						if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size))) {
+							ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
+							ast_aoc_destroy_encoded(encoded);
 						}
 					}
 					peer = o;
@@ -3361,6 +3372,14 @@
 										connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
 										ast_channel_update_connected_line(in, &connected_caller);
 										ast_party_connected_line_free(&connected_caller);
+									}
+								}
+								if (o->aoc_s_rate_list) {
+									size_t encoded_size;
+									struct ast_aoc_encoded *encoded;
+									if ((encoded = ast_aoc_encode(o->aoc_s_rate_list, &encoded_size))) {
+										ast_indicate_data(in, AST_CONTROL_AOC, encoded, encoded_size);
+										ast_aoc_destroy_encoded(encoded);
 									}
 								}
 								peer = o;
@@ -3428,6 +3447,17 @@
 							} else {
 								if (ast_channel_connected_line_macro(o->chan, in, f, 1, 1)) {
 									ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
+								}
+							}
+							break;
+						case AST_CONTROL_AOC:
+							{
+								struct ast_aoc_decoded *decoded = ast_aoc_decode(f->data.ptr, f->datalen);
+								if (decoded && (ast_aoc_get_msg_type(decoded) == AST_AOC_S)) {
+									ast_aoc_destroy_decoded(o->aoc_s_rate_list);
+									o->aoc_s_rate_list = decoded;
+								} else {
+									ast_aoc_destroy_decoded(decoded);
 								}
 							}
 							break;

Modified: team/dvossel/generic_aoc/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/channels/chan_dahdi.c?view=diff&rev=256980&r1=256979&r2=256980
==============================================================================
--- team/dvossel/generic_aoc/channels/chan_dahdi.c (original)
+++ team/dvossel/generic_aoc/channels/chan_dahdi.c Mon Apr 12 15:13:12 2010
@@ -11696,6 +11696,7 @@
 						pris[span].pri.facilityenable = conf->pri.pri.facilityenable;
 #if defined(HAVE_PRI_AOC_EVENTS)
 						pris[span].pri.aoc_grant_flag = conf->pri.pri.aoc_grant_flag;
+						pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag;
 						pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup;
 #endif
 						ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list));
@@ -17092,14 +17093,24 @@
 				confp->pri.pri.facilityenable = ast_true(v->value);
 #if defined(HAVE_PRI_AOC_EVENTS)
 			} else if (!strcasecmp(v->name, "aoc_grant_request")) {
-				if (strchr(v->value, 's')) {
+				if (strchr(v->value, 's') || strchr(v->value, 'S')) {
 					confp->pri.pri.aoc_grant_flag |= PRI_AOC_GRANT_S;
 				}
-				if (strchr(v->value, 'd')) {
+				if (strchr(v->value, 'd') || strchr(v->value, 'D')) {
 					confp->pri.pri.aoc_grant_flag |= PRI_AOC_GRANT_D;
 				}
-				if (strchr(v->value, 'e')) {
+				if (strchr(v->value, 'e') || strchr(v->value, 'E')) {
 					confp->pri.pri.aoc_grant_flag |= PRI_AOC_GRANT_E;
+				}
+			} else if (!strcasecmp(v->name, "aoc_enable")) {
+				if (strchr(v->value, 's') || strchr(v->value, 'S')) {
+					confp->pri.pri.aoc_passthrough_flag |= PRI_AOC_GRANT_S;
+				}
+				if (strchr(v->value, 'd') || strchr(v->value, 'D')) {
+					confp->pri.pri.aoc_passthrough_flag |= PRI_AOC_GRANT_D;
+				}
+				if (strchr(v->value, 'e') || strchr(v->value, 'E')) {
+					confp->pri.pri.aoc_passthrough_flag |= PRI_AOC_GRANT_E;
 				}
 			} else if (!strcasecmp(v->name, "aoce_delayhangup")) {
 				confp->pri.pri.aoce_delayhangup = ast_true(v->value);

Modified: team/dvossel/generic_aoc/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/channels/sig_pri.c?view=diff&rev=256980&r1=256979&r2=256980
==============================================================================
--- team/dvossel/generic_aoc/channels/sig_pri.c (original)
+++ team/dvossel/generic_aoc/channels/sig_pri.c Mon Apr 12 15:13:12 2010
@@ -2134,7 +2134,7 @@
  *
  * \return Nothing
  */
-static void sig_pri_aoc_s_from_pri(const struct pri_subcmd_aoc_s *aoc_s, struct ast_channel *owner)
+static void sig_pri_aoc_s_from_pri(const struct pri_subcmd_aoc_s *aoc_s, struct ast_channel *owner, int passthrough)
 {
 	struct ast_aoc_decoded *decoded = NULL;
 	struct ast_aoc_encoded *encoded = NULL;
@@ -2199,7 +2199,7 @@
 		}
 	}
 
-	if ((encoded = ast_aoc_encode(decoded, &encoded_size))) {
+	if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size))) {
 		ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
 	}
 
@@ -2232,11 +2232,6 @@
 	}
 
 	request = aoc_request->charging_request;
-
-	if (request & PRI_AOC_REQUEST_S) {
-		/* sending AOC-S has not been implemented yet */
-		pri_aoc_charging_request_response(pri->pri, call, PRI_AOC_REQUEST_RESPONSE_ERROR_NOT_IMPLEMENTED, aoc_request);
-	}
 
 	if (request & PRI_AOC_REQUEST_D) {
 		if (pri->aoc_grant_flag & PRI_AOC_GRANT_D) {
@@ -2270,7 +2265,7 @@
  *
  * \return Nothing
  */
-static void sig_pri_aoc_d_from_pri(const struct pri_subcmd_aoc_d *aoc_d, struct ast_channel *owner)
+static void sig_pri_aoc_d_from_pri(const struct pri_subcmd_aoc_d *aoc_d, struct ast_channel *owner, int passthrough)
 {
 
 	struct ast_aoc_decoded *decoded = NULL;
@@ -2335,7 +2330,7 @@
 		}
 	}
 
-	if ((encoded = ast_aoc_encode(decoded, &encoded_size))) {
+	if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size))) {
 		ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
 	}
 
@@ -2357,10 +2352,11 @@
  *
  * \note Assumes the pri->lock is already obtained.
  * \note Assumes the owner channel lock is already obtained.
+ * \note owner channel may be NULL. In that case, generate event only
  *
  * \return Nothing
  */
-static void sig_pri_aoc_e_from_pri(const struct pri_subcmd_aoc_e *aoc_e, struct ast_channel *owner)
+static void sig_pri_aoc_e_from_pri(const struct pri_subcmd_aoc_e *aoc_e, struct ast_channel *owner, int passthrough)
 {
 	struct ast_aoc_decoded *decoded = NULL;
 	struct ast_aoc_encoded *encoded = NULL;
@@ -2453,7 +2449,7 @@
 		}
 	}
 
-	if (owner && (encoded = ast_aoc_encode(decoded, &encoded_size))) {
+	if (passthrough && owner && (encoded = ast_aoc_encode(decoded, &encoded_size))) {
 		ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
 	}
 
@@ -2470,14 +2466,13 @@
  * \brief send an AOC-S message on the current call
  *
  * \param pvt sig_pri private channel structure.
- * \param ast Asterisk channel
  * \param generic decoded ast AOC message
  *
  * \return Nothing
  *
  * \note Assumes that the PRI lock is already obtained.
  */
-static void sig_pri_aoc_s_from_ast(struct sig_pri_chan *pvt, struct ast_channel *ast, struct ast_aoc_decoded *decoded)
+static void sig_pri_aoc_s_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
 {
 	struct pri_subcmd_aoc_s aoc_s = { 0, };
 	const struct ast_aoc_s_entry *entry;
@@ -2564,14 +2559,13 @@
  * \brief send an AOC-D message on the current call
  *
  * \param pvt sig_pri private channel structure.
- * \param ast Asterisk channel
  * \param generic decoded ast AOC message
  *
  * \return Nothing
  *
  * \note Assumes that the PRI lock is already obtained.
  */
-static void sig_pri_aoc_d_from_ast(struct sig_pri_chan *pvt, struct ast_channel *ast, struct ast_aoc_decoded *decoded)
+static void sig_pri_aoc_d_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
 {
 	struct pri_subcmd_aoc_d aoc_d = { 0, };
 	aoc_d.billing_accumulation = (ast_aoc_get_total_type(decoded) == AST_AOC_TOTAL) ? 1 : 0;
@@ -2637,14 +2631,13 @@
  * \brief send an AOC-E message on the current call
  *
  * \param pvt sig_pri private channel structure.
- * \param ast Asterisk channel
  * \param generic decoded ast AOC message
  *
  * \return Nothing
  *
  * \note Assumes that the PRI lock is already obtained.
  */
-static void sig_pri_aoc_e_from_ast(struct sig_pri_chan *pvt, struct ast_channel *ast, struct ast_aoc_decoded *decoded)
+static void sig_pri_aoc_e_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
 {
 	struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e;
 
@@ -2992,7 +2985,7 @@
 #if defined(HAVE_PRI_AOC_EVENTS)
 		case PRI_SUBCMD_AOC_E:
 			/* Queue AST_CONTROL_AOC frame */
-			sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL);
+			sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL, 0);
 			break;
 #endif	/* defined(HAVE_PRI_AOC_EVENTS) */
 		default:
@@ -3276,7 +3269,7 @@
 			sig_pri_lock_owner(pri, chanpos);
 			owner = pri->pvts[chanpos]->owner;
 			if (owner) {
-				sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner);
+				sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner, (pri->aoc_passthrough_flag & PRI_AOC_GRANT_S));
 				ast_channel_unlock(owner);
 			}
 			break;
@@ -3287,7 +3280,7 @@
 			owner = pri->pvts[chanpos]->owner;
 			if (owner) {
 				/* Queue AST_CONTROL_AOC frame on channel */
-				sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner);
+				sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner, (pri->aoc_passthrough_flag & PRI_AOC_GRANT_D));
 				ast_channel_unlock(owner);
 			}
 			break;
@@ -3297,7 +3290,7 @@
 			sig_pri_lock_owner(pri, chanpos);
 			owner = pri->pvts[chanpos]->owner;
 			/* Queue AST_CONTROL_AOC frame */
-			sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner);
+			sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner, (pri->aoc_passthrough_flag & PRI_AOC_GRANT_E));
 			if (owner) {
 				ast_channel_unlock(owner);
 			}
@@ -5076,6 +5069,7 @@
 
 #if defined(HAVE_PRI_AOC_EVENTS)
 	p->holding_aoce = 0;
+	p->waiting_for_aoce = 0;
 #endif
 
 	ast->tech_pvt = NULL;
@@ -5721,13 +5715,19 @@
 			if (decoded && p->pri && !pri_grab(p, p->pri)) {
 				switch (ast_aoc_get_msg_type(decoded)) {
 				case AST_AOC_S:
-					sig_pri_aoc_s_from_ast(p, chan, decoded);
+					if (p->pri->aoc_passthrough_flag & PRI_AOC_GRANT_S) {
+						sig_pri_aoc_s_from_ast(p, decoded);
+					}
 					break;
 				case AST_AOC_D:
-					sig_pri_aoc_d_from_ast(p, chan, decoded);
+					if (p->pri->aoc_passthrough_flag & PRI_AOC_GRANT_D) {
+						sig_pri_aoc_d_from_ast(p, decoded);
+					}
 					break;
 				case AST_AOC_E:
-					sig_pri_aoc_e_from_ast(p, chan, decoded);
+					if (p->pri->aoc_passthrough_flag & PRI_AOC_GRANT_E) {
+						sig_pri_aoc_e_from_ast(p, decoded);
+					}
 					/* if hangup was delayed for this AOC-E msg, waiting_for_aoc
 					 * will be set.  A hangup is already occuring via a timeout during
 					 * this delay.  Instead of waiting for that timeout to occur, go ahead
@@ -5739,15 +5739,12 @@
 					}
 					break;
 				case AST_AOC_REQUEST:
-					/* We do not pass through requests except on call setup.
-					 * So unless this is a AOC termination request it will be
-					 * ignored */
+					/* We do not pass through AOC requests, So unless this
+					 * is an AOC termination request it will be ignored */
 					if (ast_aoc_get_termination_request(decoded)) {
 						pri_hangup(p->pri->pri, p->call, -1);
 					}
-
 				default:
-					/* not supported for pass-through yet */
 					break;
 				};
 				pri_rel(p->pri);

Modified: team/dvossel/generic_aoc/channels/sig_pri.h
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/channels/sig_pri.h?view=diff&rev=256980&r1=256979&r2=256980
==============================================================================
--- team/dvossel/generic_aoc/channels/sig_pri.h (original)
+++ team/dvossel/generic_aoc/channels/sig_pri.h Mon Apr 12 15:13:12 2010
@@ -351,7 +351,8 @@
 
 #if defined(HAVE_PRI_AOC_EVENTS)
 	int aoc_grant_flag;
-	int aoce_delayhangup;
+	int aoc_passthrough_flag;
+	int aoce_delayhangup:1;
 #endif
 };
 

Modified: team/dvossel/generic_aoc/configs/chan_dahdi.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/generic_aoc/configs/chan_dahdi.conf.sample?view=diff&rev=256980&r1=256979&r2=256980
==============================================================================
--- team/dvossel/generic_aoc/configs/chan_dahdi.conf.sample (original)
+++ team/dvossel/generic_aoc/configs/chan_dahdi.conf.sample Mon Apr 12 15:13:12 2010
@@ -289,18 +289,30 @@
 ;
 ;facilityenable = yes
 ;
+
+; This option enables Advice of Charge pass-through between the ISDN PRI and
+; Asterisk.  This option can be set to any combination of 's', 'd', and 'e' which
+; represent the different variants of Advice of Charge, AOC-S, AOC-D, and AOC-E.
+; Advice of Charge pass-through is currently only supported for ETSI.
+;
+;aoc_enable=s,d,e
+;
 ; Granting Advice of Charge requests for AOC-D and AOC-E messages means that
-; he response to these requests will indicate that these services will
+; the response to these requests will indicate that these services will
 ; be provided during the call.  This option can be set to either 'd', 'e', or
 ; both 'd,e'. Without setting this option AOC requests will be responded to
 ; as service not available.
+;
 ;aoc_grant_request=d,e
-
-; When this option is enabled, a hangup initiated by the technology (or pri) side of the channel
-; will result in the ast channel delaying it's hangup in an attempt to recieve the final
-; AOC-E message from its bridge.  If the ast channel is not bridged the hangup will occur immediatly.
+;
+; When this option is enabled, a hangup initiated by the ISDN PRI side of the
+; asterisk channel will result in the channel delaying its hangup in an
+; attempt to receive the final AOC-E message from its bridge.  If the channel
+; is not bridged the hangup will occur immediatly without delay.
+;
 ;aoce_delayhangup=yes
-;
+
+
 ; pritimer cannot be changed on a reload.
 ;
 ; Signalling method. The default is "auto". Valid values:




More information about the asterisk-commits mailing list