[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