[svn-commits] mattf: branch mattf/bug13495 r163158 - /team/mattf/bug13495/channels/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Dec 11 11:31:35 CST 2008


Author: mattf
Date: Thu Dec 11 11:31:34 2008
New Revision: 163158

URL: http://svn.digium.com/view/asterisk?view=rev&rev=163158
Log:
Using this as development branch until we get ANSI support tested.  Starting on ISUP masquerade and clustering support, initial check in of this code.

Modified:
    team/mattf/bug13495/channels/chan_dahdi.c

Modified: team/mattf/bug13495/channels/chan_dahdi.c
URL: http://svn.digium.com/view/asterisk/team/mattf/bug13495/channels/chan_dahdi.c?view=diff&rev=163158&r1=163157&r2=163158
==============================================================================
--- team/mattf/bug13495/channels/chan_dahdi.c (original)
+++ team/mattf/bug13495/channels/chan_dahdi.c Thu Dec 11 11:31:34 2008
@@ -389,18 +389,22 @@
 #define SS7_BLOCKED_MAINTENANCE	(1 << 0)
 #define SS7_BLOCKED_HARDWARE	(1 << 1)
 
+#define SS7_MAX_SLAVES 100
+
 struct dahdi_ss7 {
 	pthread_t master;						/*!< Thread of master */
 	ast_mutex_t lock;
-	int fds[NUM_DCHANS];
+	int fds[NUM_DCHANS + SS7_MAX_SLAVES];
 	int numsigchans;
 	int linkstate[NUM_DCHANS];
 	int numchans;
 	int type;
+
 	enum {
 		LINKSET_STATE_DOWN = 0,
 		LINKSET_STATE_UP
 	} state;
+
 	char called_nai;						/*!< Called Nature of Address Indicator */
 	char calling_nai;						/*!< Calling Nature of Address Indicator */
 	char internationalprefix[10];					/*!< country access code ('00' for european dialplans) */
@@ -413,6 +417,23 @@
 	int flags;							/*!< Linkset flags */
 	int ss7type;
 };
+
+struct slave_channel {
+	int linksetnum;
+	int startcic;
+	int endcic;
+	unsigned int opc;
+	char addr[64];
+};
+
+struct slave_chan_server {
+	int fd;
+
+	pthread_t master;
+	struct slave_channel slave_channel[SS7_MAX_SLAVES];
+	int numslaves;
+
+} slave_chan_server;
 
 static struct dahdi_ss7 linksets[NUM_SPANS];
 
@@ -981,6 +1002,93 @@
 #endif
 
 #ifdef HAVE_SS7
+
+#define SS7_SLAVE_SERVER_PORT 7777
+
+static struct dahdi_ss7 * ss7_resolve_linkset(int linkset);
+
+static void * ss7_slave_server(void * data)
+{
+	struct sockaddr_in my_addr, slave_addr;
+	int slave_sock;
+	int i;
+	unsigned int len;
+
+	if ((slave_chan_server.fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+		ast_log(LOG_ERROR, "Unable to open socket for SS7 slave server\n");
+		return NULL;
+	}
+
+	memset(&my_addr, 0, sizeof(my_addr));
+	my_addr.sin_family = AF_INET;
+	my_addr.sin_port = htons(SS7_SLAVE_SERVER_PORT);
+	my_addr.sin_addr.s_addr = htons(INADDR_ANY);
+
+	if (bind(slave_chan_server.fd, (struct sockaddr *) &my_addr, sizeof(my_addr))) {
+		ast_log(LOG_ERROR, "Unable to bind to port %d in SS7 slave server\n", 7777);
+		close(slave_chan_server.fd);
+		return NULL;
+	}
+
+	if (listen(slave_chan_server.fd, SS7_MAX_SLAVES) == -1) {
+		ast_log(LOG_ERROR, "Unable to set max slaves on listen for SS7 slave server\n");
+		close(slave_chan_server.fd);
+		return NULL;
+	}
+
+	while (1) {
+do_accept:
+		if ((slave_sock = accept(slave_chan_server.fd, (struct sockaddr *) &slave_addr, &len)) == -1) {
+			ast_log(LOG_ERROR, "Error in accept: %s\n", strerror(errno));
+			continue;
+		}
+
+		for (i = 0; i < slave_chan_server.numslaves; i++) {
+			if (!strcasecmp(ast_inet_ntoa(slave_addr.sin_addr), slave_chan_server.slave_channel[i].addr)) {
+				struct dahdi_ss7 *ss7 = ss7_resolve_linkset(slave_chan_server.slave_channel[i].linksetnum);
+
+				ast_log(LOG_NOTICE, "Accepting SS7 slave connection from host %s\n", ast_inet_ntoa(slave_addr.sin_addr));
+
+				ast_mutex_lock(&ss7->lock);
+
+				isup_masquerade_add_route(ss7->ss7, slave_sock,
+						slave_chan_server.slave_channel[i].startcic,
+						slave_chan_server.slave_channel[i].endcic,
+						slave_chan_server.slave_channel[i].opc);
+
+				ss7->fds[ss7->numsigchans++] = slave_sock;
+				/* XXX */
+				ast_mutex_unlock(&ss7->lock);
+				goto do_accept;
+			}
+		}
+
+		/* If we get here, it is an unrecognized host trying to register */
+		ast_log(LOG_WARNING, "Unrecognized host %s tried to register with SS7 slave server\n", ast_inet_ntoa(slave_addr.sin_addr));
+		close(slave_sock);
+	}
+}
+
+static void ss7_add_slave_to_server(const char *addr)
+{
+	if (slave_chan_server.numslaves >= SS7_MAX_SLAVES) {
+		ast_log(LOG_ERROR, "Max slave channels reached (%d)\n", MAX_SLAVES);
+		return;
+	}
+
+	sscanf(addr, "%s,%d,%d-%d", 
+		slave_chan_server.slave_channel[slave_chan_server.numslaves].addr,
+		&slave_chan_server.slave_channel[slave_chan_server.numslaves].opc,
+		&slave_chan_server.slave_channel[slave_chan_server.numslaves].startcic,
+		&slave_chan_server.slave_channel[slave_chan_server.numslaves].endcic);
+
+
+	slave_chan_server.slave_channel[slave_chan_server.numslaves].linksetnum = cur_linkset;
+	slave_chan_server.numslaves++;
+
+	return;
+}
+
 static int ss7_find_alloc_call(struct dahdi_pvt *p);
 static int ss7_do_rsc(struct dahdi_pvt *p);
 
@@ -10341,10 +10449,10 @@
 				}
 				break;
 			case MTP2_LINK_UP:
-				ast_verbose("MTP2 link up (SLC %d)\n", e->gen.data);
+				ast_verbose("MTP2 link up\n");
 				break;
 			case MTP2_LINK_DOWN:
-				ast_log(LOG_WARNING, "MTP2 link down (SLC %d)\n", e->gen.data);
+				ast_log(LOG_WARNING, "MTP2 link down\n");
 				break;
 			case ISUP_EVENT_CPG:
 				chanpos = ss7_find_cic(linkset, e->cpg.cic, e->cpg.opc);
@@ -14060,7 +14168,7 @@
 }
 
 #ifdef HAVE_SS7
-static int linkset_addsigchan(int sigchan)
+static int linkset_addsigchan(const char *sigchanstr)
 {
 	struct dahdi_ss7 *link;
 	int res;
@@ -14068,7 +14176,20 @@
 	struct dahdi_params p;
 	struct dahdi_bufferinfo bi;
 	struct dahdi_spaninfo si;
-
+	char mysigstr[128];
+	char *tech = "DAHDI";
+	char *addr;
+
+	ast_copy_string(mysigstr, sigchanstr, sizeof(mysigstr));
+
+	addr = strchr(mysigstr, '/');
+
+	if (addr) {
+		*addr++ = 0;
+		tech = mysigstr;
+	} else {
+		addr = mysigstr;
+	}
 
 	link = ss7_resolve_linkset(cur_linkset);
 	if (!link) {
@@ -14099,7 +14220,7 @@
 	} else
 		ss7_set_pc(link->ss7, cur_pointcode);
 
-	if (sigchan < 0) {
+	if (ast_strlen_zero(addr)) {
 		ast_log(LOG_ERROR, "Invalid sigchan!\n");
 		return -1;
 	} else {
@@ -14107,62 +14228,86 @@
 			ast_log(LOG_ERROR, "Too many sigchans on linkset %d\n", cur_linkset);
 			return -1;
 		}
+
 		curfd = link->numsigchans;
 
-		link->fds[curfd] = open("/dev/dahdi/channel", O_RDWR, 0600);
-		if ((link->fds[curfd] < 0) || (ioctl(link->fds[curfd],DAHDI_SPECIFY,&sigchan) == -1)) {
-			ast_log(LOG_ERROR, "Unable to open SS7 sigchan %d (%s)\n", sigchan, strerror(errno));
-			return -1;
-		}
-		res = ioctl(link->fds[curfd], DAHDI_GET_PARAMS, &p);
-		if (res) {
-			dahdi_close_ss7_fd(link, curfd);
-			ast_log(LOG_ERROR, "Unable to get parameters for sigchan %d (%s)\n", sigchan, strerror(errno));
-			return -1;
-		}
-		if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC) && (p.sigtype != DAHDI_SIG_MTP2)) {
-			dahdi_close_ss7_fd(link, curfd);
-			ast_log(LOG_ERROR, "sigchan %d is not in HDLC/FCS mode.\n", sigchan);
-			return -1;
-		}
-
-		bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
-		bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
-		bi.numbufs = 32;
-		bi.bufsize = 512;
-
-		if (ioctl(link->fds[curfd], DAHDI_SET_BUFINFO, &bi)) {
-			ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", sigchan, strerror(errno));
-			dahdi_close_ss7_fd(link, curfd);
-			return -1;
-		}
-
-		if (cur_adjpointcode < 0) {
-			ast_log(LOG_ERROR, "Unspecified adjpointcode!\n");
-			return -1;
-		}
-
-		if (p.sigtype == DAHDI_SIG_MTP2)
-			ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIMTP2, link->fds[curfd], cur_slc, cur_adjpointcode);
-		else
-			ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIDCHAN, link->fds[curfd], cur_slc, cur_adjpointcode);
+		if (!strcasecmp("DAHDI", tech)) {
+			int sigchan = atoi(addr);
+
+			link->fds[curfd] = open("/dev/dahdi/channel", O_RDWR, 0600);
+			if ((link->fds[curfd] < 0) || (ioctl(link->fds[curfd],DAHDI_SPECIFY,&sigchan) == -1)) {
+				ast_log(LOG_ERROR, "Unable to open SS7 sigchan %d (%s)\n", sigchan, strerror(errno));
+				return -1;
+			}
+			res = ioctl(link->fds[curfd], DAHDI_GET_PARAMS, &p);
+			if (res) {
+				dahdi_close_ss7_fd(link, curfd);
+				ast_log(LOG_ERROR, "Unable to get parameters for sigchan %d (%s)\n", sigchan, strerror(errno));
+				return -1;
+			}
+			if ((p.sigtype != DAHDI_SIG_HDLCFCS) && (p.sigtype != DAHDI_SIG_HARDHDLC) && (p.sigtype != DAHDI_SIG_MTP2)) {
+				dahdi_close_ss7_fd(link, curfd);
+				ast_log(LOG_ERROR, "sigchan %d is not in HDLC/FCS mode.\n", sigchan);
+				return -1;
+			}
+
+			bi.txbufpolicy = DAHDI_POLICY_IMMEDIATE;
+			bi.rxbufpolicy = DAHDI_POLICY_IMMEDIATE;
+			bi.numbufs = 32;
+			bi.bufsize = 512;
+
+			if (ioctl(link->fds[curfd], DAHDI_SET_BUFINFO, &bi)) {
+				ast_log(LOG_ERROR, "Unable to set appropriate buffering on channel %d: %s\n", sigchan, strerror(errno));
+				dahdi_close_ss7_fd(link, curfd);
+				return -1;
+			}
+
+			if (cur_adjpointcode < 0) {
+				ast_log(LOG_ERROR, "Unspecified adjpointcode!\n");
+				return -1;
+			}
+
+			if (p.sigtype == DAHDI_SIG_MTP2)
+				ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIMTP2, link->fds[curfd], cur_slc, cur_adjpointcode);
+			else
+				ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIDCHAN, link->fds[curfd], cur_slc, cur_adjpointcode);
+
+			memset(&si, 0, sizeof(si));
+			res = ioctl(link->fds[curfd], DAHDI_SPANSTAT, &si);
+			if (res) {
+				dahdi_close_ss7_fd(link, curfd);
+				ast_log(LOG_ERROR, "Unable to get span state for sigchan %d (%s)\n", sigchan, strerror(errno));
+			}
+
+			if (!si.alarms) {
+				link->linkstate[curfd] = LINKSTATE_DOWN;
+				ss7_link_noalarm(link->ss7, link->fds[curfd]);
+			} else {
+				link->linkstate[curfd] = LINKSTATE_DOWN | LINKSTATE_INALARM;
+				ss7_link_alarm(link->ss7, link->fds[curfd]);
+			}
+		} else if (!strcasecmp("tcp", tech)) {
+			struct sockaddr_in my_addr;
+
+			if ((link->fds[curfd] = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+				ast_log(LOG_ERROR, "Unable to open socket for SS7 slave server\n");
+				return -1;
+			}
+			
+			memset(&my_addr, 0, sizeof(my_addr));
+			my_addr.sin_family = AF_INET;
+			my_addr.sin_port = htons(SS7_SLAVE_SERVER_PORT);
+			my_addr.sin_addr.s_addr = inet_addr(addr);
+
+			if (connect(link->fds[curfd], &my_addr, sizeof(my_addr)) == -1) {
+				ast_log(LOG_ERROR, "Unable to make initial connection.  Retrying later\n");
+			}
+
+			ss7_add_link(link->ss7, SS7_TRANSPORT_TCP, link->fds[curfd], cur_slc, cur_adjpointcode);
+		}
 
 		link->numsigchans++;
 
-		memset(&si, 0, sizeof(si));
-		res = ioctl(link->fds[curfd], DAHDI_SPANSTAT, &si);
-		if (res) {
-			dahdi_close_ss7_fd(link, curfd);
-			ast_log(LOG_ERROR, "Unable to get span state for sigchan %d (%s)\n", sigchan, strerror(errno));
-		}
-
-		if (!si.alarms) {
-			link->linkstate[curfd] = LINKSTATE_DOWN;
-			ss7_link_noalarm(link->ss7, link->fds[curfd]);
-		} else {
-			link->linkstate[curfd] = LINKSTATE_DOWN | LINKSTATE_INALARM;
-			ss7_link_alarm(link->ss7, link->fds[curfd]);
-		}
 	}
 
 	if (cur_defaultdpc < 0) {
@@ -16209,6 +16354,8 @@
 				ast_copy_string(confp->ss7.unknownprefix, v->value, sizeof(confp->ss7.unknownprefix));
 			} else if (!strcasecmp(v->name, "ss7_networkroutedprefix")) {
 				ast_copy_string(confp->ss7.networkroutedprefix, v->value, sizeof(confp->ss7.networkroutedprefix));
+			} else if (!strcasecmp(v->name, "ss7_slave_channel")) {
+				ss7_add_slave_to_server(v->value);
 			} else if (!strcasecmp(v->name, "ss7_called_nai")) {
 				if (!strcasecmp(v->value, "national")) {
 					confp->ss7.called_nai = SS7_NAI_NATIONAL;
@@ -16234,9 +16381,8 @@
 					ast_log(LOG_WARNING, "Unknown SS7 calling_nai '%s' at line %d.\n", v->value, v->lineno);
 				}
 			} else if (!strcasecmp(v->name, "sigchan")) {
-				int sigchan, res;
-				sigchan = atoi(v->value);
-				res = linkset_addsigchan(sigchan);
+				int res;
+				res = linkset_addsigchan(v->value);
 				if (res < 0)
 					return -1;
 
@@ -16689,6 +16835,13 @@
 					ast_verb(2, "Starting SS7 linkset on span %d\n", x + 1);
 			}
 		}
+
+		if (slave_chan_server.numslaves) {
+			if (ast_pthread_create(&slave_chan_server.master, NULL, ss7_slave_server, NULL)) {
+				ast_log(LOG_ERROR, "Unable to start SS7 slave chan server\n");
+			} else
+				ast_verb(2, "Starting SS7 slave channel server\n");
+		}
 	}
 #endif
 	/* And start the monitor for the first time */




More information about the svn-commits mailing list