[asterisk-commits] crichter: trunk r86616 - in /trunk/channels: ./ misdn/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Oct 22 05:04:06 CDT 2007


Author: crichter
Date: Mon Oct 22 05:04:04 2007
New Revision: 86616

URL: http://svn.digium.com/view/asterisk?view=rev&rev=86616
Log:
started to add some basic support for supplementary services like CallForwarding and so forth

Modified:
    trunk/channels/chan_misdn.c
    trunk/channels/misdn/isdn_lib.c
    trunk/channels/misdn/isdn_lib.h
    trunk/channels/misdn/isdn_msg_parser.c

Modified: trunk/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_misdn.c?view=diff&rev=86616&r1=86615&r2=86616
==============================================================================
--- trunk/channels/chan_misdn.c (original)
+++ trunk/channels/chan_misdn.c Mon Oct 22 05:04:04 2007
@@ -452,38 +452,46 @@
 static void print_facility(struct FacParm *fac, struct misdn_bchannel *bc)
 {
 	switch (fac->Function) {
-	case Fac_CD:
-		chan_misdn_log(1,bc->port," --> calldeflect to: %s, screened: %s\n", fac->u.CDeflection.DeflectedToNumber,
-					   fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
-		break;
-	case Fac_AOCDCurrency:
-		if (fac->u.AOCDcur.chargeNotAvailable)
-			chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n");
-		else if (fac->u.AOCDcur.freeOfCharge)
-			chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n");
-		else if (fac->u.AOCDchu.billingId >= 0)
-			chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d billingId:%d\n",
-						   fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
-						   (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
-		else
-			chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d\n",
-						   fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
-						   (fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
-		break;
-	case Fac_AOCDChargingUnit:
-		if (fac->u.AOCDchu.chargeNotAvailable)
-			chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n");
-		else if (fac->u.AOCDchu.freeOfCharge)
-			chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n");
-		else if (fac->u.AOCDchu.billingId >= 0)
-			chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
-						   fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
-		else
-			chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
-						   fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
-		break;
-	default:
-		chan_misdn_log(1,bc->port," --> unknown\n");
+		case Fac_RESULT:
+			chan_misdn_log(0, bc->port," --> Received RESULT Operation\n");
+			break;
+		case Fac_ERROR:
+			chan_misdn_log(0, bc->port," --> Received Error Operation\n");
+			chan_misdn_log(0, bc->port," --> Value:%d Error:%s\n",fac->u.ERROR.errorValue, fac->u.ERROR.error);
+			break;
+		case Fac_CD:
+			chan_misdn_log(1,bc->port," --> calldeflect to: %s, screened: %s\n", fac->u.CDeflection.DeflectedToNumber,
+					fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
+			break;
+		case Fac_AOCDCurrency:
+			if (fac->u.AOCDcur.chargeNotAvailable)
+				chan_misdn_log(1,bc->port," --> AOCD currency: charge not available\n");
+			else if (fac->u.AOCDcur.freeOfCharge)
+				chan_misdn_log(1,bc->port," --> AOCD currency: free of charge\n");
+			else if (fac->u.AOCDchu.billingId >= 0)
+				chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d billingId:%d\n",
+						fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
+						(fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDcur.billingId);
+			else
+				chan_misdn_log(1,bc->port," --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%d\n",
+						fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
+						(fac->u.AOCDcur.typeOfChargingInfo == 0) ? "subTotal" : "total");
+			break;
+		case Fac_AOCDChargingUnit:
+			if (fac->u.AOCDchu.chargeNotAvailable)
+				chan_misdn_log(1,bc->port," --> AOCD charging unit: charge not available\n");
+			else if (fac->u.AOCDchu.freeOfCharge)
+				chan_misdn_log(1,bc->port," --> AOCD charging unit: free of charge\n");
+			else if (fac->u.AOCDchu.billingId >= 0)
+				chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
+						fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total", fac->u.AOCDchu.billingId);
+			else
+				chan_misdn_log(1,bc->port," --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
+						fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ? "subTotal" : "total");
+			break;
+		case Fac_None:
+		default:
+			chan_misdn_log(1,bc->port," --> unknown facility\n");
 	}
 }
 
@@ -1417,44 +1425,93 @@
 	return CLI_SUCCESS;
 }
 
-static char *handle_cli_misdn_send_calldeflect(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static char *handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	char *channame; 
 	char *nr;
 	struct chan_list *tmp;
-
-	switch (cmd) {
+	int port; 
+	char *served_nr;
+	struct misdn_bchannel dummy, *bc=&dummy;
+ 
+ 	switch (cmd) {
 	case CLI_INIT:
-		e->command = "misdn send calldeflect";
-		e->usage =
-			"Usage: misdn send calldeflect <channel> \"<nr>\"\n"
-			"       Send CallDeflection to mISDN Channel.\n";
+		e->command = "misdn send facility";
+		e->usage = "Usage: misdn send facility <type> <channel|port> \"<args>\" \n"
+		"\t type is one of:\n"
+		"\t - calldeflect\n"
+		"\t - CFActivate\n"
+		"\t - CFDeactivate\n";
+
 		return NULL;
 	case CLI_GENERATE:
 		return complete_ch(a);
 	}
 
-	if (a->argc != 5)
+	if (a->argc < 5)
 		return CLI_SHOWUSAGE;
-
-	channame = a->argv[3];
-	nr = a->argv[4];
-
-	ast_cli(a->fd, "Sending Calldeflection (%s) to %s\n", nr, channame);
-	
-	tmp = get_chan_by_ast_name(channame);
-	if (!tmp) {
-		ast_cli(a->fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
-		return CLI_SUCCESS;
-	}
-
-	if (strlen(nr) >= 15) {
-		ast_cli(a->fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n", nr, channame);
-		return CLI_SUCCESS;
-	}
-	tmp->bc->fac_out.Function = Fac_CD;
-	ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
-	misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
+ 
+	if (strstr(a->argv[3], "calldeflect")) {
+		if (a->argc < 6) {
+			ast_verbose("calldeflect requires 1 arg: ToNumber\n\n");
+			return 0;
+		}
+		channame = a->argv[4];
+		nr = a->argv[5];
+
+		ast_verbose("Sending Calldeflection (%s) to %s\n", nr, channame);
+		tmp = get_chan_by_ast_name(channame);
+		if (!tmp) {
+			ast_verbose("Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame);
+			return 0; 
+		}
+
+		if (strlen(nr) >= 15) {
+			ast_verbose("Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame);
+			return 0; 
+		}
+		tmp->bc->fac_out.Function = Fac_CD;
+		ast_copy_string((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
+		misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
+	} else if (strstr(a->argv[3],"CFActivate")) {
+		if (a->argc < 7) {
+			ast_verbose("CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
+			return 0;
+		}
+		port = atoi(a->argv[4]);
+		served_nr = a->argv[5];
+		nr = a->argv[6];
+
+		misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
+
+		ast_verbose("Sending CFActivate  Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr);
+
+		bc->fac_out.Function = Fac_CFActivate;
+		bc->fac_out.u.CFActivate.BasicService = 0; //All Services
+		bc->fac_out.u.CFActivate.Procedure = 0; //Unconditional
+		ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
+		ast_copy_string((char *)bc->fac_out.u.CFActivate.ForwardedToNumber, nr, sizeof(bc->fac_out.u.CFActivate.ForwardedToNumber));
+
+		misdn_lib_send_event(bc, EVENT_FACILITY);
+	} else if (strstr(a->argv[3],"CFDeactivate")) {
+
+		if (a->argc < 6) {
+			ast_verbose("CFActivate requires 1 arg: FromNumber\n\n");
+			return 0;
+		}
+		port = atoi(a->argv[4]);
+		served_nr = a->argv[5];
+		
+		misdn_make_dummy(bc, port, 0, misdn_lib_port_is_nt(port), 0);
+		ast_verbose("Sending CFDeactivate  Port:(%d) FromNr. (%s)\n", port, served_nr);
+
+		bc->fac_out.Function = Fac_CFDeactivate;
+		bc->fac_out.u.CFDeactivate.BasicService = 0; //All Services
+		bc->fac_out.u.CFDeactivate.Procedure = 0; //Unconditional
+		
+		ast_copy_string((char *)bc->fac_out.u.CFActivate.ServedUserNumber, served_nr, sizeof(bc->fac_out.u.CFActivate.ServedUserNumber));
+		misdn_lib_send_event(bc, EVENT_FACILITY);
+	}
 
 	return CLI_SUCCESS;
 }
@@ -1720,7 +1777,7 @@
 	AST_CLI(handle_cli_misdn_show_port,         "Show detailed information for given port"),
 	AST_CLI(handle_cli_misdn_show_ports_stats,  "Show mISDNs channel's call statistics per port"),
 	AST_CLI(handle_cli_misdn_show_stacks,       "Show internal mISDN stack_list"),
-	AST_CLI(handle_cli_misdn_send_calldeflect,  "Send CallDeflection to mISDN Channel"),
+	AST_CLI(handle_cli_misdn_send_facility,     "Sends a Facility Message to the mISDN Channel"),
 	AST_CLI(handle_cli_misdn_send_digit,        "Send DTMF digit to mISDN Channel"),
 	AST_CLI(handle_cli_misdn_send_display,      "Send Text to mISDN Channel"),
 	AST_CLI(handle_cli_misdn_send_restart,      "Send a restart for every bchannel on the given port"),
@@ -4850,17 +4907,13 @@
 	break;
 	
 	case EVENT_FACILITY:
-		if (!ch) {
-			/* This may come from a call we don't know nothing about, so we ignore it. */
-			chan_misdn_log(-1, bc->port, "Got EVENT_FACILITY but we don't have a ch!\n");
-			break;
-		}
-
 		print_facility(&(bc->fac_in), bc);
 		
 		switch (bc->fac_in.Function) {
+		case Fac_RESULT:
+		break;
 		case Fac_CD:
-			{
+			if (ch) {
 				struct ast_channel *bridged = ast_bridged_channel(ch->ast);
 				struct chan_list *ch_br;
 				if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
@@ -4879,17 +4932,24 @@
 			} 
 			break;
 		case Fac_AOCDCurrency:
-			bc->AOCDtype = Fac_AOCDCurrency;
-			memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(bc->AOCD.currency));
-			bc->AOCD_need_export = 1;
-			export_aoc_vars(ch->originator, ch->ast, bc);
+			if (ch) {
+				bc->AOCDtype = Fac_AOCDCurrency;
+				memcpy(&(bc->AOCD.currency), &(bc->fac_in.u.AOCDcur), sizeof(bc->AOCD.currency));
+				bc->AOCD_need_export = 1;
+				export_aoc_vars(ch->originator, ch->ast, bc);
+			}
 			break;
 		case Fac_AOCDChargingUnit:
-			bc->AOCDtype = Fac_AOCDChargingUnit;
-			memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(bc->AOCD.chargingUnit));
-			bc->AOCD_need_export = 1;
-			export_aoc_vars(ch->originator, ch->ast, bc);
-			break;
+			if (ch) {
+				bc->AOCDtype = Fac_AOCDChargingUnit;
+				memcpy(&(bc->AOCD.chargingUnit), &(bc->fac_in.u.AOCDchu), sizeof(bc->AOCD.chargingUnit));
+				bc->AOCD_need_export = 1;
+				export_aoc_vars(ch->originator, ch->ast, bc);
+			}
+			break;
+		case Fac_None:
+		case Fac_ERROR:
+		break;
 		default:
 			chan_misdn_log(0, bc->port," --> not yet handled: facility type:%p\n", bc->fac_in.Function);
 		}

Modified: trunk/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_lib.c?view=diff&rev=86616&r1=86615&r2=86616
==============================================================================
--- trunk/channels/misdn/isdn_lib.c (original)
+++ trunk/channels/misdn/isdn_lib.c Mon Oct 22 05:04:04 2007
@@ -41,11 +41,27 @@
 	return -1;
 }
 
-static void make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel) 
+int misdn_lib_port_is_nt(int port)
+{
+	struct misdn_stack *stack=get_misdn_stack();
+	for ( ; stack; stack=stack->next) {
+		if (stack->port == port) {
+			return stack->nt;
+		}
+	}
+	
+	return -1;
+}
+
+void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel) 
 {
 	memset (dummybc,0,sizeof(struct misdn_bchannel));
 	dummybc->port=port;
-	dummybc->l3_id=l3id;
+	if (l3id==0) 
+		dummybc->l3_id = MISDN_ID_DUMMY;
+	else
+		dummybc->l3_id=l3id;
+
 	dummybc->nt=nt;
 	dummybc->dummy=1;
 	dummybc->channel=channel;
@@ -1619,7 +1635,7 @@
       
 			if (!bc) {
 				cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
-				make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
+				misdn_make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
 				
 				bc=&dummybc; 
 			}
@@ -1930,7 +1946,7 @@
 			/** removing procid **/
 			if (!bc) {
 				cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x) on this port.\n", hh->dinfo);
-				make_dummy(&dummybc, stack->port, hh->dinfo, stack->nt, 0);
+				misdn_make_dummy(&dummybc, stack->port, hh->dinfo, stack->nt, 0);
 				bc=&dummybc; 
 			}
 	
@@ -2029,7 +2045,7 @@
     
 		if (!bc) {
 			cb_log(4, stack->port, " --> Didn't found BC so temporarly creating dummy BC (l3id:%x).\n", hh->dinfo);
-			make_dummy(&dummybc, stack->port,  hh->dinfo, stack->nt, 0);
+			misdn_make_dummy(&dummybc, stack->port,  hh->dinfo, stack->nt, 0);
 			bc=&dummybc; 
 		}
 		if (bc ) {
@@ -2586,7 +2602,7 @@
 		bc=find_bc_by_l3id(stack, frm->dinfo);
 
 		if (!bc && (frm->prim==(CC_RESTART|CONFIRM)) ) {
-			make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
+			misdn_make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
 			bc=&dummybc;
 		}
     
@@ -2681,7 +2697,11 @@
       
 		} else {
 			struct misdn_bchannel dummybc;
-			cb_log(0, stack->port, " --> Didn't find BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
+			if (frm->prim!=(CC_FACILITY|INDICATION))
+				cb_log(0, stack->port, " --> Didn't find BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
+			else
+				cb_log(5, stack->port, " --> Using Dummy BC for FACILITy\n");
+
 			memset (&dummybc,0,sizeof(dummybc));
 			dummybc.port=stack->port;
 			dummybc.l3_id=frm->dinfo;
@@ -3673,7 +3693,7 @@
 	
 	cb_log(0, port, "Sending Restarts on this port.\n");
 	
-	make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
+	misdn_make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
 
 	/*if a channel is specified we restart only this one*/
 	if (channel > 0) {
@@ -3825,10 +3845,13 @@
 					if (bc) 
 						send_msg(glob_mgr->midev, bc, msg);
 					else  {
-						if (frm->dinfo == MISDN_ID_GLOBAL) {
+						if (frm->dinfo == MISDN_ID_GLOBAL || frm->dinfo == MISDN_ID_DUMMY ) {
 							struct misdn_bchannel dummybc;
-							make_dummy(&dummybc, stack->port, MISDN_ID_GLOBAL, stack->nt, 0);
+							cb_log(5,0," --> GLOBAL/DUMMY\n");
+							misdn_make_dummy(&dummybc, stack->port, frm->dinfo, stack->nt, 0);
 							send_msg(glob_mgr->midev, &dummybc, msg);
+						} else {
+							cb_log(0,0,"No bc for Message\n");
 						}
 					}
 				}

Modified: trunk/channels/misdn/isdn_lib.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_lib.h?view=diff&rev=86616&r1=86615&r2=86616
==============================================================================
--- trunk/channels/misdn/isdn_lib.h (original)
+++ trunk/channels/misdn/isdn_lib.h Mon Oct 22 05:04:04 2007
@@ -421,6 +421,7 @@
 int misdn_lib_port_unblock(int port);
 
 int misdn_lib_port_is_pri(int port);
+int misdn_lib_port_is_nt(int port);
 
 int misdn_lib_port_up(int port, int notcheck);
 
@@ -472,4 +473,7 @@
 
 void misdn_dump_chanlist(void);
 
+void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel);
+
+
 #endif

Modified: trunk/channels/misdn/isdn_msg_parser.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_msg_parser.c?view=diff&rev=86616&r1=86615&r2=86616
==============================================================================
--- trunk/channels/misdn/isdn_msg_parser.c (original)
+++ trunk/channels/misdn/isdn_msg_parser.c Mon Oct 22 05:04:04 2007
@@ -965,7 +965,7 @@
 	
 	err = decodeFac(p, &(bc->fac_in));
 	if (err) {
-		cb_log(1, bc->port, "Decoding FACILITY failed! (%d)\n", err);
+		cb_log(5, bc->port, "Decoding FACILITY failed! (%d)\n", err);
 	}
 }
 




More information about the asterisk-commits mailing list