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

📄 chan_ss7.c

📁 asterisk 中国七号驱动修改代码可以在ASTERISIK-1。4上编译pa
💻 C
📖 第 1 页 / 共 2 页
字号:
  dump_do_fisu = fisu;  dump_do_lssu = lssu;  dump_do_msu = msu;  init_pcap_file(fh);  ast_mutex_unlock(&dump_mutex);  return RESULT_SUCCESS;}static int cmd_dump_stop(int fd, int argc, char *argv[]) {  int in, out;  if(argc == 3) {    in = 1;    out = 1;  } else if(argc == 4) {    if(0 == strcasecmp(argv[3], "in")) {      in = 1;      out = 0;    } else if(0 == strcasecmp(argv[3], "out")) {      in = 0;      out = 1;    } else if(0 == strcasecmp(argv[3], "both")) {      in = 1;      out = 1;    } else {      return RESULT_SHOWUSAGE;    }  } else {    return RESULT_SHOWUSAGE;  }  ast_mutex_lock(&dump_mutex);  if((in && !out && dump_in_fh == NULL) ||     (out && !in && dump_out_fh == NULL) ||     (in && out && dump_in_fh == NULL && dump_out_fh == NULL)) {    ast_cli(fd, "No dump running.\n");    ast_mutex_unlock(&dump_mutex);    return RESULT_SUCCESS;  }  if(in && dump_in_fh != NULL) {    if(dump_out_fh == dump_in_fh) {      /* Avoid closing it twice. */      dump_out_fh = NULL;    }    fclose(dump_in_fh);    dump_in_fh = NULL;  }  if(out && dump_out_fh != NULL) {    fclose(dump_out_fh);    dump_out_fh = NULL;  }  ast_mutex_unlock(&dump_mutex);  return RESULT_SUCCESS;}static int cmd_dump_status(int fd, int argc, char *argv[]) {  ast_mutex_lock(&dump_mutex);  /* ToDo: This doesn't seem to work, the output is getting lost somehow.     Not sure why, but could be related to ast_carefulwrite() called in     ast_cli(). */  ast_cli(fd, "Yuck! what is going on here?!?\n");  if(dump_in_fh != NULL) {    ast_cli(fd, "Dump of incoming frames is running.\n");  }  if(dump_out_fh != NULL) {    ast_cli(fd, "Dump of outgoing frames is running.\n");  }  if(dump_in_fh != NULL || dump_out_fh != NULL) {    ast_cli(fd, "Filter:%s%s%s.\n",            (dump_do_fisu ? " fisu" : ""),            (dump_do_lssu ? " lssu" : ""),            (dump_do_msu ? " msu" : ""));  }  ast_mutex_unlock(&dump_mutex);  return RESULT_SUCCESS;}static int cmd_version(int fd, int argc, char *argv[]){  ast_cli(fd, "chan_ss7 version %s\n", CHAN_SS7_VERSION);  return RESULT_SUCCESS;}static int cmd_ss7_status(int fd, int argc, char *argv[]){  cmd_linkset_status(fd, argc, argv);  return RESULT_SUCCESS;}static void process_event(struct mtp_event* event){  FILE *dump_fh;  switch(event->typ) {  case MTP_EVENT_ISUP:    l4isup_event(event);    break;  case MTP_EVENT_SCCP:    break;  case MTP_EVENT_REQ_REGISTER:    if (event->regist.ss7_protocol == 5) {      struct link* link = &links[event->regist.isup.slinkix];      mtp3_register_isup(link->mtp3fd, link->linkix);    }    break;  case MTP_EVENT_LOG:    ast_log(event->log.level, event->log.file, event->log.line,	    event->log.function, "%s", event->buf);    break;  case MTP_EVENT_DUMP:    ast_mutex_lock(&dump_mutex);    if(event->dump.out) {      dump_fh = dump_out_fh;    } else {      dump_fh = dump_in_fh;    }    if(dump_fh != NULL) {      if(event->len < 3 ||	 ( !(event->buf[2] == 0 && !dump_do_fisu) &&	   !((event->buf[2] == 1 || event->buf[2] == 2) && !dump_do_lssu) &&	   !(event->buf[2] > 2 && !dump_do_msu)))	dump_pcap(dump_fh, event);    }    ast_mutex_unlock(&dump_mutex);    break;  case MTP_EVENT_STATUS:    {      struct link* link = event->status.link;      char* name = link ? link->name : "(peer)";      switch(event->status.link_state) {      case MTP_EVENT_STATUS_LINK_UP:	l4isup_link_status_change(link, 1);	ast_log(LOG_WARNING, "MTP is now UP on link '%s'.\n", name);	break;      case MTP_EVENT_STATUS_LINK_DOWN:	l4isup_link_status_change(link, 0);	ast_log(LOG_WARNING, "MTP is now DOWN on link '%s'.\n", name);	break;      case MTP_EVENT_STATUS_INSERVICE:	ast_log(LOG_WARNING, "Signaling ready for linkset '%s'.\n", link->linkset->name);	l4isup_inservice(link);	break;      default:	ast_log(LOG_NOTICE, "Unknown event type STATUS (%d), "		"not processed.\n", event->status.link_state);      }    }    break;  default:    ast_log(LOG_NOTICE, "Unexpected mtp event type %d.\n", event->typ);  }}/* Monitor thread main loop.   Monitor reads events from the realtime MTP thread, and processes them at   non-realtime priority. It also handles timers for ISUP etc.*/static void *monitor_main(void *data) {  int res, nres;  struct pollfd fds[(MAX_LINKS+1)];  int i, n_fds;  int rebuild_fds = 1;  struct lffifo *receive_fifo = mtp_get_receive_fifo();  ast_verbose(VERBOSE_PREFIX_3 "Starting monitor thread, pid=%d.\n", getpid());  fds[0].fd = get_receive_pipe();  fds[0].events = POLLIN;  while(monitor_running) {    if (rebuild_fds) {      if (rebuild_fds > 1)	poll(fds, 0, 200); /* sleep */      rebuild_fds = 0;      n_fds = 1;      for (i = 0; i < n_linksets; i++) {	struct linkset* linkset = &linksets[i];	int j;	for (j = 0; j < linkset->n_links; j++) {	  int k;	  struct link* link = linkset->links[j];	  for (k = 0; k < this_host->n_spans; k++) {	    if (this_host->spans[k].link == link)	      break;	    if ((this_host->spans[k].link->linkset == link->linkset) ||		(is_combined_linkset(this_host->spans[k].link->linkset, link->linkset)))	      break;	  }	  if (k < this_host->n_spans) {	    if (link->remote) {	      if (link->mtp3fd == -1) {		link->mtp3fd = mtp3_connect_socket(link->mtp3server_host, link->mtp3server_port);		if (link->mtp3fd != -1)		  res = mtp3_register_isup(link->mtp3fd, link->linkix);		if ((link->mtp3fd == -1) || (res == -1))		  rebuild_fds += 2;	      }	      fds[n_fds].fd = link->mtp3fd;	      fds[n_fds++].events = POLLIN|POLLERR|POLLNVAL|POLLHUP;	    }	  }	}      }    }    int timeout = timers_wait();    nres = poll(fds, n_fds, timeout);    if(nres < 0) {      if(errno == EINTR) {        /* Just try again. */      } else {        ast_log(LOG_ERROR, "poll() failure, errno=%d: %s\n",                errno, strerror(errno));      }    } else if(nres > 0) {      for (i = 0; (i < n_fds) && (nres > 0); i++) {	unsigned char eventbuf[MTP_EVENT_MAX_SIZE];	struct mtp_event *event = (struct mtp_event*) eventbuf;	struct link* link = NULL;	if(fds[i].revents) {	  int j;	  for (j = 0; j < n_links; j++) {	    link = &links[j];	    if (link->remote && (link->mtp3fd == fds[i].fd))	      break;	  }	  if (j == n_links)	    link = NULL;	}	else	  continue;	if(fds[i].revents & (POLLERR|POLLNVAL|POLLHUP)) {	  close(fds[i].fd);	  if (link)	    link->mtp3fd = -1;	  rebuild_fds++; rebuild_fds++; /* when > 1, use short sleep */	  nres--;	  continue;	}	if(!fds[i].revents & POLLIN)	  continue;	if (i == 0) {	  /* Events waiting in the receive buffer. */	  unsigned char dummy[512];	  /* Empty the pipe before pulling from fifo. This way the race	     condition between mtp and monitor threads may cause spurious	     wakeups, but not loss/delay of messages. */	  read(fds[i].fd, dummy, sizeof(dummy));	  /* Process all available events. */	  while((res = lffifo_get(receive_fifo, eventbuf, sizeof(eventbuf))) != 0) {	    if(res < 0) {	      ast_log(LOG_ERROR, "Yuck! oversized frame in receive fifo, bailing out.\n");	      return NULL;	    }	    process_event(event);	  }	}	else {#if MTP3_SOCKET == SOCK_STREAM	  res = read(fds[i].fd, eventbuf, sizeof(struct mtp_event));	  if ((res > 0) && (event->len > 0)) {	    int p = res;	    int len = event->len;	    if (sizeof(struct mtp_event) + event->len > MTP_EVENT_MAX_SIZE) {	      ast_log(LOG_NOTICE, "Got too large packet: len %d, max %d, discarded", sizeof(struct mtp_event) + event->len, MTP_EVENT_MAX_SIZE);	      len = 0;	      res = 0;	    }	    do {	      res = read(fds[i].fd, &eventbuf[p], len);	      if (res > 0) {		p += res;		len -= res;	      }	      else if ((res < 0) && (errno != EINTR)) {		len = 0;	      }	      else {		len = 0;	      }	    } while (len > 0);	  }#else	  res = read(fds[i].fd, eventbuf, sizeof(eventbuf)+MTP_MAX_PCK_SIZE);#endif	  if (res > 0) {	    if (event->typ == MTP_EVENT_ISUP) {	      event->isup.link = NULL;	      event->isup.slink = &links[event->isup.slinkix];	    }	    process_event(event);	  }	  else if (res == 0) {	    int j;	    for (j = 0; j < n_links; j++) {	      struct link* link = &links[j];	      if (link->remote && (link->mtp3fd == fds[i].fd)) {		close(fds[i].fd);		link->mtp3fd = -1;		rebuild_fds++;	      }	    }	  }	}	nres--;      }    }    /* We need to lock the global glock mutex around ast_sched_runq() so that       we avoid a race with ss7_hangup. With the lock, invalidating the       channel in ss7_hangup() and removing associated monitor_sched entries       is an atomic operation, so that we avoid calling timer handlers with       references to invalidated channels. */    run_timers();  }  return NULL;}static void stop_monitor(void) {  int i;  if(monitor_running) {    monitor_running = 0;    /* Monitor wakes up every 1/2 sec, so no need to signal it explicitly. */    pthread_join(monitor_thread, NULL);  }  for (i = 0; i < n_links; i++) {    struct link* link = &links[i];    if (link->remote && (link->mtp3fd > -1))      close(link->mtp3fd);  }}static int ss7_reload_module(void) {  ast_log(LOG_NOTICE, "SS7 reload not implemented.\n");  return AST_MODULE_LOAD_SUCCESS;}static int ss7_load_module(void){  if(load_config(0)) {    return AST_MODULE_LOAD_FAILURE;  }  if (timers_init()) {    ast_log(LOG_ERROR, "Unable to initialize timers.\n");    return AST_MODULE_LOAD_FAILURE;  }  if (isup_init()) {    ast_log(LOG_ERROR, "Unable to initialize ISUP.\n");    return AST_MODULE_LOAD_FAILURE;  }#ifdef SCCP  if (sccp_init()) {    ast_log(LOG_ERROR, "Unable to initialize SCCP.\n");    return AST_MODULE_LOAD_FAILURE;  }#endif  if(mtp_init()) {    ast_log(LOG_ERROR, "Unable to initialize MTP.\n");    return AST_MODULE_LOAD_FAILURE;  }  if(start_mtp_thread()) {    ast_log(LOG_ERROR, "Unable to start MTP thread.\n");    return AST_MODULE_LOAD_FAILURE;  }  mtp_control_fifo = mtp_get_control_fifo();  monitor_running = 1;          /* Otherwise there is a race, and                                   monitor may exit immediately */  if(ast_pthread_create(&monitor_thread, NULL, monitor_main, NULL) < 0) {    ast_log(LOG_ERROR, "Unable to start monitor thread.\n");    monitor_running = 0;    return AST_MODULE_LOAD_FAILURE;  }  ast_cli_register_multiple(my_clis, sizeof(my_clis)/ sizeof(my_clis[0]));  ast_verbose(VERBOSE_PREFIX_3 "SS7 channel loaded successfully.\n");  return AST_MODULE_LOAD_SUCCESS;}static int ss7_unload_module(void){  ast_cli_unregister_multiple(my_clis, sizeof(my_clis)/ sizeof(my_clis[0]));#ifdef SCCP  sccp_cleanup();#endif  isup_cleanup();  ast_mutex_lock(&dump_mutex);  if(dump_in_fh != NULL) {    if(dump_in_fh == dump_out_fh) {      dump_out_fh = NULL;    }    fclose(dump_in_fh);    dump_in_fh = NULL;  }  if(dump_out_fh != NULL) {    fclose(dump_out_fh);    dump_out_fh = NULL;  }  ast_mutex_unlock(&dump_mutex);  if(monitor_running) {    stop_monitor();  }  stop_mtp_thread();  mtp_cleanup();  timers_cleanup();  destroy_config();  ast_verbose(VERBOSE_PREFIX_3 "SS7 channel unloaded.\n");  return AST_MODULE_LOAD_SUCCESS;}#ifdef USE_ASTERISK_1_2int reload(void){  return ss7_reload_module();}int load_module(void){  return ss7_load_module();}int unload_module(void){  return ss7_unload_module();}char *description() {  return (char *) desc;}char *key() {  return ASTERISK_GPL_KEY;}#else#define AST_MODULE "chan_ss7"AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, desc,                .load = ss7_load_module,                .unload = ss7_unload_module,                .reload = ss7_reload_module,);#endif

⌨️ 快捷键说明

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