[asterisk-commits] mattf: branch mattf/bug13495 r170939 - /team/mattf/bug13495/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Jan 24 15:59:37 CST 2009


Author: mattf
Date: Sat Jan 24 15:59:37 2009
New Revision: 170939

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=170939
Log:
Change API so that we are able to handle IP based links that change file descriptors when they go up and down

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

Modified: team/mattf/bug13495/channels/chan_dahdi.c
URL: http://svn.digium.com/svn-view/asterisk/team/mattf/bug13495/channels/chan_dahdi.c?view=diff&rev=170939&r1=170938&r2=170939
==============================================================================
--- team/mattf/bug13495/channels/chan_dahdi.c (original)
+++ team/mattf/bug13495/channels/chan_dahdi.c Sat Jan 24 15:59:37 2009
@@ -391,10 +391,20 @@
 
 #define SS7_MAX_SLAVES 100
 
+struct dahdi_ss7;
+
+struct ss7_start_tcp_data {
+	struct dahdi_ss7 *ss7;
+	int linkindex;
+	pthread_t thread;
+};
+
 struct dahdi_ss7 {
 	pthread_t master;						/*!< Thread of master */
 	ast_mutex_t lock;
-	int fds[NUM_DCHANS + SS7_MAX_SLAVES];
+	int fds[NUM_DCHANS + SS7_MAX_SLAVES]; 			/*!< list of fds that we should poll */
+	char sigchans[NUM_DCHANS + SS7_MAX_SLAVES][128];	/*!< sigchan identifer string.  Contains address, etc */
+	struct ss7_start_tcp_data start_thread_info[NUM_DCHANS]; /*!< Since we're only starting threads for normal links (not masq'd links) we only need NUM_DCHANS */
 	int numsigchans;
 	int linkstate[NUM_DCHANS];
 	int numchans;
@@ -417,6 +427,7 @@
 	int flags;							/*!< Linkset flags */
 	int ss7type;
 };
+
 
 struct slave_channel {
 	int linksetnum;
@@ -1054,17 +1065,17 @@
 				if ((flags = fcntl(slave_sock, F_GETFL)) < 0) {
 					ast_log(LOG_WARNING,"Fcntl(F_GETFL) failed: %s\n", strerror(errno));
 					close(slave_sock);
-					continue;
+					goto do_accept;
 				}
 				if (fcntl(slave_sock, F_SETFL, flags | O_NONBLOCK) < 0) {
 					ast_log(LOG_WARNING,"Fnctl(F_SETFL) failed: %s\n", strerror(errno));
 					close(slave_sock);
-					continue;
+					goto do_accept;
 				}
 
 				ast_mutex_lock(&ss7->lock);
 
-				isup_masquerade_add_route(ss7->ss7, slave_sock,
+				isup_masquerade_set_route_fd(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);
@@ -1088,6 +1099,7 @@
 static void ss7_add_slave_to_server(const char *addr)
 {
 	int ip1, ip2, ip3, ip4;
+	struct dahdi_ss7 *ss7 = ss7_resolve_linkset(cur_linkset);
 
 	if (slave_chan_server.numslaves >= SS7_MAX_SLAVES) {
 		ast_log(LOG_ERROR, "Max slave channels reached (%d)\n", SS7_MAX_SLAVES);
@@ -1121,7 +1133,14 @@
 		slave_chan_server.slave_channel[slave_chan_server.numslaves].startcic,
 		slave_chan_server.slave_channel[slave_chan_server.numslaves].endcic);
 
+	/* Add the masquerade route to declare its existance */
+	isup_masquerade_add_route(ss7->ss7,
+		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].opc);
+
 	slave_chan_server.numslaves++;
+
 	return;
 }
 
@@ -10362,16 +10381,85 @@
 	
 }
 
+static void *ss7_start_tcp_channel_thread(void *vdata)
+{
+	struct ss7_start_tcp_data *data = vdata;
+	struct sockaddr_in my_addr;
+	int flags;
+	int curfd = data->linkindex;
+	int fd;
+	char mysigstr[128];
+	struct dahdi_ss7 *link = data->ss7;
+	char *addr;
+
+	ast_copy_string(mysigstr, link->sigchans[curfd], sizeof(mysigstr));
+
+	addr = strchr(mysigstr, '/');
+
+	*addr++ = 0;
+
+retry:
+	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+		ast_log(LOG_ERROR, "Unable to open socket for SS7 slave server\n");
+		goto retry;
+	}
+	
+	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(fd, &my_addr, sizeof(my_addr)) == -1) {
+		ast_log(LOG_ERROR, "Unable to make initial connection.  Retrying later\n");
+		close(fd);
+		goto retry;
+	}
+
+	if ((flags = fcntl(fd, F_GETFL)) < 0) {
+		ast_log(LOG_WARNING,"Fcntl(F_GETFL) failed: %s\n", strerror(errno));
+		close(fd);
+		goto retry;
+	}
+	if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+		ast_log(LOG_WARNING,"Fnctl(F_SETFL) failed: %s\n", strerror(errno));
+		close(fd);
+		goto retry;
+	}
+
+	ast_mutex_lock(&link->lock);
+
+	ss7_set_link_fd(link->ss7, link->sigchans[curfd], fd);
+	link->fds[curfd] = fd;
+
+	pthread_kill(link->master, SIGURG);
+
+	ast_mutex_unlock(&link->lock);
+
+	return NULL;
+}
+
+static void ss7_start_tcp_channel(struct dahdi_ss7 *ss7, int linkindex)
+{
+	ss7->start_thread_info[linkindex].ss7 = ss7;
+	ss7->start_thread_info[linkindex].linkindex = linkindex;
+	ss7->fds[linkindex] = -1;
+
+	ast_pthread_create(&ss7->start_thread_info[linkindex].thread,
+			NULL, ss7_start_tcp_channel_thread,
+			&ss7->start_thread_info[linkindex]);
+
+}
+
 static void *ss7_linkset(void *data)
 {
-	int res, i;
+	int res, i, j, numpollers;
 	struct timeval *next = NULL, tv;
 	struct dahdi_ss7 *linkset = (struct dahdi_ss7 *) data;
 	struct ss7 *ss7 = linkset->ss7;
 	ss7_event *e = NULL;
 	struct dahdi_pvt *p_cur, *p = NULL; /* just shut up gcc 4.1 */
 	int chanpos;
-	struct pollfd pollers[NUM_DCHANS];
+	struct pollfd pollers[NUM_DCHANS + SS7_MAX_SLAVES];
 	int cic;
 	unsigned int dpc;
 	unsigned char state[255], mb_state[255];
@@ -10399,15 +10487,20 @@
 		} else 
 			nextms = -1;
 
+		numpollers = 0;
+
 		for (i = 0; i < linkset->numsigchans; i++) {
-			pollers[i].fd = linkset->fds[i];
-			pollers[i].events = ss7_pollflags(ss7, linkset->fds[i]);
-			pollers[i].revents = 0;
+			if (linkset->fds[i] != -1) {
+				pollers[numpollers].fd = linkset->fds[i];
+				pollers[numpollers].events = ss7_pollflags(ss7, linkset->fds[i]);
+				pollers[numpollers].revents = 0;
+				numpollers++;
+			}
 		}
 
 		ast_mutex_unlock(&linkset->lock);
 
-		res = poll(pollers, linkset->numsigchans, nextms);
+		res = poll(pollers, numpollers, nextms);
 		if ((res < 0) && (errno != EINTR)) {
 			ast_log(LOG_ERROR, "poll(%s)\n", strerror(errno));
 		} else if (!res) {
@@ -10417,7 +10510,7 @@
 		}
 
 		ast_mutex_lock(&linkset->lock);
-		for (i = 0; i < linkset->numsigchans; i++) {
+		for (i = 0; i < numpollers; i++) {
 			if (pollers[i].revents & POLLPRI) {
 				int x;
 				if (ioctl(pollers[i].fd, DAHDI_GETEVENT, &x)) {
@@ -10436,14 +10529,22 @@
 					break;
 				case DAHDI_EVENT_ALARM:
 					ast_log(LOG_ERROR, "Alarm on link!\n");
-					linkset->linkstate[i] |= (LINKSTATE_DOWN | LINKSTATE_INALARM);
-					linkset->linkstate[i] &= ~LINKSTATE_UP;
+					for (j = 0; j < linkset->numsigchans; j++) {
+						if (pollers[i].fd == linkset->fds[j])
+							break;
+					}
+					linkset->linkstate[j] |= (LINKSTATE_DOWN | LINKSTATE_INALARM);
+					linkset->linkstate[j] &= ~LINKSTATE_UP;
 					ss7_link_alarm(ss7, pollers[i].fd);
 					break;
 				case DAHDI_EVENT_NOALARM:
 					ast_log(LOG_ERROR, "Alarm cleared on link\n");
-					linkset->linkstate[i] &= ~(LINKSTATE_INALARM | LINKSTATE_DOWN);
-					linkset->linkstate[i] |= LINKSTATE_STARTING;
+					for (j = 0; i < linkset->numsigchans; j++) {
+						if (pollers[i].fd == linkset->fds[j])
+							break;
+					}
+					linkset->linkstate[j] &= ~(LINKSTATE_INALARM | LINKSTATE_DOWN);
+					linkset->linkstate[j] |= LINKSTATE_STARTING;
 					ss7_link_noalarm(ss7, pollers[i].fd);
 					break;
 				default:
@@ -10490,6 +10591,17 @@
 				break;
 			case MTP2_LINK_DOWN:
 				ast_log(LOG_WARNING, "MTP2 link down\n");
+				for (i = 0; i < linkset->numsigchans; i++) {
+					if (linkset->fds[i] == e->gen.data) {
+						/* Verify that it's a TCP fd */
+						if (strcasecmp("tcp", linkset->sigchans[i])) {
+							break;
+						}
+
+						ss7_start_tcp_channel(linkset, i);
+
+					}
+				}
 				break;
 			case ISUP_EVENT_CPG:
 				chanpos = ss7_find_cic(linkset, e->cpg.cic, e->cpg.opc);
@@ -14304,10 +14416,14 @@
 				return -1;
 			}
 
+			ast_copy_string(link->sigchans[curfd], sigchanstr, 128);
+
 			if (p.sigtype == DAHDI_SIG_MTP2)
-				ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIMTP2, link->fds[curfd], cur_slc, cur_adjpointcode);
+				ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIMTP2, link->sigchans[curfd], cur_slc, cur_adjpointcode);
 			else
-				ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIDCHAN, link->fds[curfd], cur_slc, cur_adjpointcode);
+				ss7_add_link(link->ss7, SS7_TRANSPORT_DAHDIDCHAN, link->sigchans[curfd], cur_slc, cur_adjpointcode);
+
+			ss7_set_link_fd(link->ss7, link->sigchans[curfd], link->fds[curfd]);
 
 			memset(&si, 0, sizeof(si));
 			res = ioctl(link->fds[curfd], DAHDI_SPANSTAT, &si);
@@ -14324,34 +14440,11 @@
 				ss7_link_alarm(link->ss7, link->fds[curfd]);
 			}
 		} else if (!strcasecmp("tcp", tech)) {
-			struct sockaddr_in my_addr;
-			int flags;
-
-			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");
-			}
-
-			if ((flags = fcntl(link->fds[curfd], F_GETFL)) < 0) {
-				ast_log(LOG_WARNING,"Fcntl(F_GETFL) failed: %s\n", strerror(errno));
-				close(link->fds[curfd]);
-				return 0;
-			}
-			if (fcntl(link->fds[curfd], F_SETFL, flags | O_NONBLOCK) < 0) {
-				ast_log(LOG_WARNING,"Fnctl(F_SETFL) failed: %s\n", strerror(errno));
-				close(link->fds[curfd]);
-				return 0;
-			}
-			ss7_add_link(link->ss7, SS7_TRANSPORT_TCP, link->fds[curfd], cur_slc, cur_adjpointcode);
+
+			ast_copy_string(link->sigchans[curfd], sigchanstr, 128);
+
+			ss7_add_link(link->ss7, SS7_TRANSPORT_TCP, link->sigchans[curfd], cur_slc, cur_adjpointcode);
+			ss7_start_tcp_channel(link, curfd);
 		}
 
 		link->numsigchans++;




More information about the asterisk-commits mailing list