⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtp3d.c

📁 asterisk1.4.6版本下 7#信令驱动 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  }
  return 0;
}


static void mtp_mainloop(void)
{
  int res;
  struct pollfd fds[MAX_LINKS*2] = {{0,}};
  int n_listen = 0;
  int asockets[MAX_LINKS];
  int n_asockets = 0;
  int rebuild_fds = 1;
  int n_fds = 0;
  unsigned char buf[1024];
  int i, port;

  ast_verbose(VERBOSE_PREFIX_3 "Starting mtp mainloop, pid=%d.\n", getpid());

  for (i = 0; i < this_host->n_schannels; i++) {
    struct link* link = this_host->schannels[i];
    if (strcmp(link->mtp3server_host, this_host->name) == 0) {
      port = atoi(link->mtp3server_port);
      link->mtp3fd = mtp3_setup_socket(port, 0);
      if (link->mtp3fd == -1) {
        ast_log(LOG_ERROR, "Could not setup mtp3 listen port %d, %d:%s\n", port, errno, strerror(errno));
	return;
      }
      printf("Using mtp3 service port %d, socket %d\n", port, link->mtp3fd);
      n_listen++;
    }
  }
  if (!n_listen) {
    fprintf(stderr, "No signaling channels\n");
    exit(1);
  }

  while(monitor_running) {
    int timeout = 2000;
    int servsock;

  loop:
    if (rebuild_fds) {
      rebuild_fds = 0;
      n_fds = 0;

      for (i = 0; i < n_links; i++) {
	struct link* link = &links[i];
	if (link->mtp3fd > -1) {
	  fds[n_fds].fd = link->mtp3fd;
	  fds[n_fds++].events = POLLIN|POLLERR|POLLNVAL|POLLHUP;
	}
      }
      for (i = 0; i < n_asockets; i++) {
	fds[n_fds].fd = asockets[i];
	fds[n_fds++].events = POLLIN|POLLERR|POLLNVAL|POLLHUP;
      }
    }
    res = poll(fds, n_fds, timeout);
    if(res < 0) {
      if(errno == EINTR) {
        /* Just try again. */
      } else {
        ast_log(LOG_ERROR, "poll() failure, errno=%d: %s\n",
                errno, strerror(errno));
      }
    } else if(res > 0) {
      servsock = -1;
      for (i = 0; i < n_fds; i++)
	if(fds[i].revents & (POLLIN|POLLERR|POLLNVAL|POLLHUP)) {
	  servsock = fds[i].fd;
	  break;
	}
      if (servsock < 0)
	continue;
      printf("poll fd: %d, i: %d, revent 0x%04x\n", servsock, i, fds[i].revents);
      if(fds[i].revents & (POLLERR|POLLNVAL|POLLHUP)) {
	if (i < n_listen) {
	  rebuild_fds++;
	  continue;
	}
	close_socket(servsock, asockets, &n_asockets, i-n_listen);
	rebuild_fds++;
	continue;
      }
#if MTP3_SOCKETTYPE == SOCK_STREAM
      if (i < n_listen) {
	struct sockaddr_in from_addr;
	unsigned int len = sizeof(struct sockaddr_in);
	int afd = accept(servsock, (struct sockaddr *)&from_addr, &len);
	if (afd != -1) {
	  ast_log(LOG_NOTICE, "Accepted socket connection from %s, fd %d\n", inet_ntoa(from_addr.sin_addr), afd);
	  setnonblock_fd(afd);
	  asockets[n_asockets++] = afd;
	  rebuild_fds = 1;
	  continue;
	}
	else {
	  ast_log(LOG_WARNING, "Accept of receiver connection failed: %s.\n", strerror(errno));
	}
      }
#endif
      for(;;) {
	struct sockaddr_in from;
	socklen_t fromlen = sizeof(from);
	res = recvfrom(servsock, buf, sizeof(struct mtp_req), 0, &from, &fromlen);
	if(res == 0) {
	  /* EOF. */
	  close_socket(servsock, asockets, &n_asockets, i-n_listen);
	  rebuild_fds = 1;
	  break;
	} else if(res < 0) {
	  if(errno == EAGAIN || errno == EWOULDBLOCK) {
	    break;
	  } else if(errno == EINTR) {
	    /* Try again. */
	  } else {
	    /* Some unexpected error. */
	    ast_log(LOG_WARNING, "Error reading mtp3 socket %d, errno=%d: %s.\n", servsock, errno, strerror(errno));
	    close_socket(servsock, asockets, &n_asockets, i-n_listen);
	    rebuild_fds = 1;
	    break;
	  }
	} else {
	  struct mtp_req *req = (struct mtp_req *)buf;
#undef inet_ntoa
	  if (fromlen) {
	    if (from.sin_port == 0) {
	      printf("got data from invalid source %s:%d, ignoring\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port));
	    //xxx	    break;
	    }
	    printf("got data on %d %s:%d\n", servsock, inet_ntoa(from.sin_addr), ntohs(from.sin_port));
	  }
	  else
	    printf("got data on %d\n", servsock);
	  if ((req->typ == MTP_REQ_ISUP) || (req->typ == MTP_REQ_SCCP)) {
	    int p = res;
	    do {
	      res = recvfrom(servsock, &buf[p], req->len, 0, &from, &fromlen);
	      if (res == 0) {
		ast_log(LOG_WARNING, "Unexpectec EOF on mtp3 socket %d\n", servsock);
		close_socket(servsock, asockets, &n_asockets, i-n_listen);
		rebuild_fds = 1;
		goto loop;
	      }
	      else if (res < 0) {
		if(errno == EINTR) {
		  continue;
		} else {
		  /* Some unexpected error. */
		  ast_log(LOG_WARNING, "Error reading mtp3 socket %d, errno=%d: %s.\n", servsock, errno, strerror(errno));
		  close_socket(servsock, asockets, &n_asockets, i-n_listen);
		  rebuild_fds = 1;
		  goto loop;
		}
	      }
	      p += res;
	    } while ((res > 0) && (p < req->len));
	  }
	  switch (req->typ) {
	  case MTP_REQ_REGISTER_L4:
	    {
	      int i;
	      for (i = 0; i < n_registry; i++) {
		if ((registry->ss7_protocol == req->regist.ss7_protocol) &&
		    (registry[i].host_ix == req->regist.host_ix) &&
		    (memcmp(&registry[i].client.sin_addr, &from.sin_addr, sizeof(from.sin_addr))== 0) &&
		    (registry[i].link == &links[req->regist.linkix])) {
		  if (registry->ss7_protocol == SS7_PROTO_ISUP) {
		      break; /* client re-registers, possibly with new sin_port */
		  } else if (registry->ss7_protocol == SS7_PROTO_ISUP)
		    if (registry[i].sccp.subsystem == req->regist.sccp.subsystem)
		      break;
		}
	      }
	      if (i == n_registry)
		n_registry++;
	      printf("got register protocol %d, link %d, clients now %d\n", req->regist.ss7_protocol, req->regist.linkix, n_registry);
	      if (n_registry == MAXCLIENTS-1) {
		ast_log(LOG_ERROR, "Too many client connections\n");
		break;
	      }
	      registry[i].ss7_protocol = req->regist.ss7_protocol;
	      registry[i].host_ix = req->regist.host_ix;
	      registry[i].peerfd = servsock;
	      registry[i].client = from;
	      if (req->regist.linkix >= n_links) {
		ast_log(LOG_ERROR, "ISUP req register link_ix %d out of range, max %d\n", req->regist.linkix, n_links);
		break;
	      }
	      registry[i].link = &links[req->regist.linkix];
	      if ((req->regist.ss7_protocol == SS7_PROTO_ISUP) ||
		  (req->regist.ss7_protocol == SS7_PROTO_SCCP)) {
		ast_log(LOG_NOTICE, "Registered client protocol %d for link '%s'\n", req->regist.ss7_protocol, links[req->regist.linkix].name);
		if (req->regist.ss7_protocol == SS7_PROTO_SCCP) {
		  registry[i].sccp.subsystem = req->regist.sccp.subsystem;
		}
	      }
	      else
		ast_log(LOG_ERROR, "Unknown req register ss7 protocol %d.\n", req->regist.ss7_protocol);
	    }
	    break;
	  case MTP_REQ_ISUP:
	    {
	      int i;
	      struct link* link;
	      for (i = 0; i < n_registry; i++) {
		if ((memcmp((void*) &registry[i].client, (void*) &from, sizeof(from)) == 0) &&
		    (registry[i].ss7_protocol == SS7_PROTO_ISUP)) {
		  link = registry[i].link;
		  if (!mtp_send_fifo) {
		    ast_log(LOG_ERROR, "Send fifo not ready for link '%s'\n", link->name);
		    break;
		  }
		  if (!mtp_send_fifo[link->linkset->lsi]) {
		    ast_log(LOG_ERROR, "Send fifo missing for link '%s', lsi %d\n", link->name, link->linkset->lsi);
		    break;
		  }
		  req->isup.link = NULL;
		  req->isup.slink = &links[req->isup.slinkix];
		  printf("got isup req, link %s, slinkix %d\n", link->name, req->isup.slinkix);
		  res = lffifo_put(mtp_send_fifo[req->isup.slink->linkset->lsi], (unsigned char *)req, sizeof(struct mtp_req) + req->len);
		  break;
		}
	      }
	      if (i == n_registry) {
		unsigned char buf[MTP_EVENT_MAX_SIZE];
		struct mtp_event *event = (struct mtp_event*) buf;
		event->typ = MTP_EVENT_REQ_REGISTER;
		event->regist.ss7_protocol = SS7_PROTO_ISUP;
		event->regist.isup.slinkix = req->isup.slinkix;
		event->len = 0;
		mtp3_reply(servsock, (void*) buf, sizeof(*event)+event->len, (const struct sockaddr*) &from, fromlen);
	      }
	    }
	    break;
	  case MTP_REQ_SCCP:
	    {
	      int i;
	      struct link* link;
	      for (i = 0; i < n_registry; i++) {
		if ((memcmp((void*) &registry[i].client, (void*) &from, sizeof(from)) == 0) &&
		    (registry[i].ss7_protocol == SS7_PROTO_SCCP)) {
		  link = &links[req->sccp.slinkix];
		  if (!mtp_send_fifo) {
		    ast_log(LOG_ERROR, "Send fifo not ready for link '%s'\n", link->name);
		    break;
		  }
		  if (!mtp_send_fifo[link->linkset->lsi]) {
		    ast_log(LOG_ERROR, "Send fifo missing for link '%s', lsi %d\n", link->name, link->linkset->lsi);
		    break;
		  }
		  req->sccp.slink = &links[req->sccp.slinkix];
		  printf("got sccp req, link %s, slinkix %d\n", link->name, req->sccp.slinkix);
		  res = lffifo_put(mtp_send_fifo[req->sccp.slink->linkset->lsi], (unsigned char *)req, sizeof(struct mtp_req) + req->len);
		  break;
		}
	      }
	      if (i == n_registry) {
		unsigned char buf[MTP_EVENT_MAX_SIZE];
		struct mtp_event *event = (struct mtp_event*) buf;
		event->typ = MTP_EVENT_REQ_REGISTER;
		event->regist.ss7_protocol = SS7_PROTO_SCCP;
		event->len = 0;
		mtp3_reply(servsock, (void*) buf, sizeof(*event)+event->len, (const struct sockaddr*) &from, fromlen);
	      }
	    }
	    break;
	  default:
	    ast_log(LOG_NOTICE, "Unknown req type %d.\n", req->typ);
	    break;
	  }
	}
      }
    }
  }
}

static void setup_dump(const char* fn)
{
  FILE *fh;

  fh = fopen(fn, "w");
  if(fh == NULL) {
    fprintf(stderr, "Error opening file '%s': %s.\n", fn, strerror(errno));
    return;
  }

  dump_in_fh = fh;
  dump_out_fh = fh;
  dump_do_fisu = 0;
  dump_do_lssu = 0;
  dump_do_msu = 1;
  init_pcap_file(fh);
}

static void usage(void)
{
  fprintf(stderr, "usage: mtp3d [-c <configdir>] [-m <protocol-dump-file>] [-d] [-p]\n");
  exit(1);
}

  
static void sigterm(int p)
{
  monitor_running = 0;
}

static int setup_daemon(void)
{
  FILE* pidfile = fopen("/var/run/mtp3d.pid", "w");
  if (!pidfile) {
    fprintf(stderr, "Cannot open /var/run/mtp3d.pid %d: %s\n", errno, strerror(errno));
    return 1;
  }
  signal(SIGTERM, sigterm);
  fprintf(pidfile, "%d\n", getpid());
  fclose(pidfile);
  return 0;
}

int main(int argc, char* argv[])
{
  char dumpfn[PATH_MAX] = {0,};
  int c;

  strcpy(ast_config_AST_CONFIG_DIR, "/etc/asterisk");
  
  while ((c = getopt(argc, argv, "c:m:dp")) != -1) {
    switch (c) {
    case 'c':
      strcpy(ast_config_AST_CONFIG_DIR, optarg);
      break;
    case 'm':
      strcpy(dumpfn, optarg);
      break;
    case 'd':
      option_debug++;
      break;
    case 'p':
      do_pid = 1;
      break;
    default:
      usage();
    }
  }
  is_mtp3d = 1;
  printf("Using %s for config directory\n", ast_config_AST_CONFIG_DIR);
  if(load_config(0)) {
    return -1;
  }
  if (*dumpfn)
    setup_dump(dumpfn);
  if (do_pid)
    if (setup_daemon())
      return -1;
  if(mtp_init()) {
    ast_log(LOG_ERROR, "Unable to initialize MTP.\n");
    return -1;
  }
  if(start_mtp_thread()) {
    ast_log(LOG_ERROR, "Unable to start MTP thread.\n");
    return -1;
  }
  mtp_control_fifo = mtp_get_control_fifo();

  monitor_running = 1;          /* Otherwise there is a race, and
                                   monitor may exit immediately */
  if(pthread_create(&monitor_thread, NULL, monitor_main, NULL) < 0) {
    ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
    monitor_running = 0;
    return -1;
  }
  mtp_mainloop();
  stop_mtp_thread();
  return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -