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

📄 mtp.c

📁 asterisk 的7号信令处理模块
💻 C
📖 第 1 页 / 共 5 页
字号:
static void t17_stop(mtp2_t *m) {  if(m->mtp3_t17 != -1) {    mtp_sched_del(mtp2_sched, m->mtp3_t17);    m->mtp3_t17 = -1;  }}static void t17_start(mtp2_t *m) {  t17_stop(m);  m->mtp3_t17 = mtp_sched_add(mtp2_sched, 1200, t17_timeout, m);}static int t1_timeout(void *data) {  mtp2_t *m = data;  fifo_log(m, LOG_WARNING, "MTP2 timer T1 timeout (peer failed to complete "	   "initial alignment), initial alignment failed on link '%s'.\n", m->name);  m->mtp2_t1 = -1;  abort_initial_alignment(m);  return 0;                     /* Do not re-schedule */}static void t1_stop(mtp2_t *m) {  if(m->mtp2_t1 != -1) {    mtp_sched_del(mtp2_sched, m->mtp2_t1);    m->mtp2_t1 = -1;  }}static void t1_start(mtp2_t *m) {  t1_stop(m);  m->mtp2_t1 = mtp_sched_add(mtp2_sched, 45000, t1_timeout, m);}static int t2_timeout(void *data) {  mtp2_t *m = data;  fifo_log(m, LOG_WARNING, "MTP2 timer T2 timeout (failed to receive 'O', 'N', "	   "or 'E' after sending 'O'), initial alignment failed on link '%s'.\n", m->name);  m->mtp2_t2 = -1;  abort_initial_alignment(m);  return 0;                     /* Do not re-schedule */}static void t2_stop(mtp2_t *m) {  if(m->mtp2_t2 != -1) {    mtp_sched_del(mtp2_sched, m->mtp2_t2);    m->mtp2_t2 = -1;  }}static void t2_start(mtp2_t *m) {  t2_stop(m);  m->mtp2_t2 = mtp_sched_add(mtp2_sched, 75000, t2_timeout, m);}static int t3_timeout(void *data) {  mtp2_t *m = data;  fifo_log(m, LOG_WARNING, "MTP2 timer T3 timeout (failed to receive 'N', "	   "or 'E' after sending 'O'), initial alignment failed on link '%s'.\n", m->name);  m->mtp2_t3 = -1;  abort_initial_alignment(m);  return 0;                     /* Do not re-schedule */}static void t3_stop(mtp2_t *m) {  if(m->mtp2_t3 != -1) {    mtp_sched_del(mtp2_sched, m->mtp2_t3);    m->mtp2_t3 = -1;  }}static void t3_start(mtp2_t *m) {  t3_stop(m);  m->mtp2_t3 = mtp_sched_add(mtp2_sched, 1500, t3_timeout, m);}static int t4_timeout(void *data) {  mtp2_t *m = data;  fifo_log(m, LOG_DEBUG, "Proving successful on link '%s'.\n", m->name);  m->state = MTP2_READY;  m->mtp2_t4 = -1;  t1_start(m);  return 0;                     /* Do not re-schedule */}static void t4_stop(mtp2_t *m) {  if(m->mtp2_t4 != -1) {    mtp_sched_del(mtp2_sched, m->mtp2_t4);    m->mtp2_t4 = -1;  }}static void t4_start(mtp2_t *m) {  t4_stop(m);  m->mtp2_t4 = mtp_sched_add(mtp2_sched, 500, t4_timeout, m);}static struct mtp2_state* get_inservice_schannel(struct link* link){  int i;   for (i = 0; i < this_host->n_schannels; i++) {    struct mtp2_state* m = &mtp2_state[i];    if (m->state == MTP2_INSERVICE) {      struct link* slink = m->link;      if (link->linkset == slink->linkset ||	  is_combined_linkset(link->linkset, slink->linkset))	return m;    }  }  return NULL;}int mtp_has_inservice_schannels(struct link* link){  return (get_inservice_schannel(link) != NULL);}static mtp2_t* find_alternative_slink(mtp2_t* m){  struct mtp2_state* newm = NULL;  struct mtp2_state* alt_newm = NULL;  int i;   for (i = 0; i < this_host->n_schannels; i++) {    if (&mtp2_state[i] == m)      continue;    if (mtp2_state[i].state != MTP2_INSERVICE)      continue;    if (m->link->linkset == mtp2_state[i].link->linkset) {      newm = &mtp2_state[i];      break;    }    if (is_combined_linkset(m->link->linkset, mtp2_state[i].link->linkset))      alt_newm = &mtp2_state[i];  }  if (!newm)    newm = alt_newm;  return newm;}/* Flush MTP transmit buffer to other link or host */static void mtp_changeover(mtp2_t *m) {  struct mtp2_state* newm = NULL;  int i;  int do_forward = 1;  for (i = 0; i < this_host->n_schannels; i++) {    struct mtp2_state* newm = &mtp2_state[i];    if (&mtp2_state[i] == m)      continue;    if (m->link->linkset != newm->link->linkset)      continue;    if (mtp2_state[i].state == MTP2_INSERVICE) {      newm = &mtp2_state[i];      break;    }  }  if (!newm) {    fifo_log(m, LOG_NOTICE, "MTP changeover last_ack=%d, last_sent=%d, from schannel %d, no INSERVICE schannel found\n", m->retrans_last_acked, m->retrans_last_sent, m->schannel);    if (this_host->has_signalling_receivers)      fifo_log(m, LOG_NOTICE, "Failover, using another host for signalling.\n");    if (!cluster_receivers_alive(m->link->linkset)) {      fifo_log(m, LOG_NOTICE, "Failover not possible, no other signalling link and no other host available.\n");#if 1      /* Remove all MSU's - the user parts must deal with lost PDU's */      m->retrans_last_acked = MTP_NEXT_SEQ(m->retrans_last_sent);      m->retrans_seq = -1;#endif      return;    }  }  fifo_log(m, LOG_NOTICE, "MTP changeover last_ack=%d, last_sent=%d, from schannel %d, to schannel %d\n", m->retrans_last_acked, m->retrans_last_sent, m->schannel, newm ? newm->schannel : -1);  i = MTP_NEXT_SEQ(m->retrans_last_acked);  while (i != MTP_NEXT_SEQ(m->retrans_last_sent)) {    int sio = m->retrans_buf[i].buf[3];    int len = m->retrans_buf[i].len-4;    unsigned char* buf = &m->retrans_buf[i].buf[4];    fifo_log(m, LOG_DEBUG, "MTP changeover seqno=%d, sio=%d, len=%d, is_moved=%d\n", i, sio, len, (sio & 0xf) > 3);    if (do_forward && ((sio & 0xf) >= 3)) { /* User and application parts */      if (newm) {	mtp2_queue_msu(newm, sio, buf, len);      }      else {	if ((sio & 0xf) == 0x5 /* ISUP */) {	  unsigned char reqbuf[MTP_REQ_MAX_SIZE];	  struct mtp_req *req = (struct mtp_req*) &reqbuf;	  memcpy(req->buf, buf, len);	  req->len = len;	  req->typ = MTP_REQ_ISUP;	  cluster_mtp_forward(req);	}      }      m->retrans_buf[i].buf[3] = 0;      m->retrans_buf[i].len = 5; /* Is now a LSSU */      m->retrans_buf[i].buf[3] = 2;      i = MTP_NEXT_SEQ(i);    }  }}/* Called on link errors that occur during initial alignment (before the link   is in service), and which should cause initial alignment to be aborted. The   initial alignment to be re-tried after a short delay (MTP3 T17). */static void abort_initial_alignment(mtp2_t *m){  mtp2_cleanup(m);  m->state = MTP2_DOWN;  /* Retry the initial alignment after a small delay. */  t17_start(m);  fifo_log(m, LOG_DEBUG, "Aborted initial alignment on link '%s'.\n", m->name);}/* Called on link errors that occur after the link is brought into service and   which must cause the link to be brought out of service. This entails   notifying user-parts of the failure and initiating MTP3 link failover, when   that is implemented. */static void mtp3_link_fail(mtp2_t *m, int down) {  struct mtp_event link_up_event;  int old_state = m->state;  mtp2_cleanup(m);  /* Notify user-parts. */  if(old_state == MTP2_INSERVICE) {    link_up_event.typ = MTP_EVENT_STATUS;    link_up_event.status.link_state = MTP_EVENT_STATUS_LINK_DOWN;    link_up_event.status.link = m->link;    link_up_event.len = 0;    mtp_put(m, &link_up_event);    mtp_changeover(m);  }  /* For now, restart initial alignment after a small delay. */  if (down) {    m->state = MTP2_DOWN;    t17_start(m);  }  else    m->state = MTP2_NOT_ALIGNED;  l4down(m);  fifo_log(m, LOG_DEBUG, "Fail on link '%s'.\n", m->name);}static void start_initial_alignment(mtp2_t *m, char* reason) {  m->state = MTP2_NOT_ALIGNED;  m->send_fib = 1;  m->send_bsn = 0x7f;  m->send_bib = 1;  m->tx_len = 0;  m->tx_sofar = 0;  m->retrans_seq = -1;  m->retrans_last_acked = 0x7f;  m->retrans_last_sent = 0x7f;  m->error_rate_mon = 0;  m->emon_dcount = 0;  m->emon_ncount = 0;  m->bsn_errors = 0;  fifo_log(m, LOG_DEBUG, "Starting initial alignment on link '%s', reason: %s.\n", m->name, reason);  t2_start(m);}static void t7_stop(mtp2_t *m) {  if(m->mtp2_t7 != -1) {    mtp_sched_del(mtp2_sched, m->mtp2_t7);    m->mtp2_t7 = -1;  }}static void mtp2_cleanup(mtp2_t *m) {  /* Stop SLTA response timeout. */  if(m->sltm_t1 != -1) {    mtp_sched_del(mtp2_sched, m->sltm_t1);    m->sltm_t1 = -1;  }  /* Stop sending SLTM. */  if(m->sltm_t2 != -1) {    mtp_sched_del(mtp2_sched, m->sltm_t2);    m->sltm_t2 = -1;  }  t1_stop(m);  t2_stop(m);  t3_stop(m);  t4_stop(m);  t7_stop(m);  t17_stop(m);}static void deliver_l4(mtp2_t *m, unsigned char *sif, int len, int sio) {  unsigned char ebuf[MTP_EVENT_MAX_SIZE];  struct mtp_event *event = (struct mtp_event *)ebuf;  if (sio == MTP_EVENT_ISUP) {    event->isup.link = NULL;    event->isup.slink = m->link;    event->isup.slinkix = m->link->linkix;  }  else{    event->sccp.slink = m->link;    event->sccp.slinkix = m->link->linkix;  }  event->typ = sio;  event->len = len;  memcpy(event->buf, sif, len);  mtp_put(m, event);}static int timeout_t7(void *data) {  mtp2_t *m = data;  m->mtp2_t7 = -1;  fifo_log(m, LOG_WARNING, "T7 timeout (excessive delay of acknowledgement) on link '%s', state=%d.\n", m->name, m->state);  mtp3_link_fail(m, 1);  return 0;                     /* Do not schedule us again. */}static void mtp2_t7_start(mtp2_t *m) {  t7_stop(m);  m->mtp2_t7 = mtp_sched_add(mtp2_sched, 1500, timeout_t7, m);}/* Signal unit error rate monitor (Q.703 (10.2)) */static void mtp2_error_mon_count_frame(mtp2_t *m) {  if(m->state == MTP2_READY || m->state == MTP2_INSERVICE) {    m->emon_dcount = (m->emon_dcount + 1) % 256;    if(m->emon_dcount == 0 && m->error_rate_mon > 0) {      (m->error_rate_mon)--;    }  }}static void mtp2_octet_counting(mtp2_t *m) {  m->emon_ncount = 0;}static void mtp2_emon_count_error(mtp2_t *m) {  if(m->state == MTP2_READY || m->state == MTP2_INSERVICE) {    if(m->error_rate_mon < 64) {      (m->error_rate_mon)++;      if(m->error_rate_mon == 64) {        fifo_log(m, LOG_WARNING, "Excessive errors detected in signalling unit "		 "error rate monitor, link failed on link '%s'.\n", m->name);        mtp3_link_fail(m, 0);      }    }  } else if(m->state == MTP2_PROVING) {    (m->error_rate_mon)++;    /* ToDo: For now we are always in emergency, but for non       emergency, proving is not aborted until error_rate_mon reaches       the value of 4 (Q.703 (10.3.4)). */    if(m->error_rate_mon >= 1) {      fifo_log(m, LOG_WARNING, "Excessive errors detected in alignment "	       "error rate monitor, link failed on link '%s'.\n", m->name);      abort_initial_alignment(m);      /* ToDo: Abort the entire initial alingment, if proving is aborted for         the fifth time. */    }  }}static void mtp2_bad_frame(mtp2_t *m, char* msg) {  char buf[3 * sizeof(m->backbuf) + 1];  int i;  struct timeval now;  static struct timeval last = {0, 0};  static int badcount = 0;  gettimeofday(&now, NULL);  if (last.tv_sec) {    int tdiff = (now.tv_sec - last.tv_sec) * 1000000 + (now.tv_usec - last.tv_usec);    if (tdiff < 10*1000000 && badcount < 10000) {      badcount++;      return;    }    else {      if (badcount) {	fifo_log(m, LOG_DEBUG, "Suppressed %d bad frame debug log messages on link '%s'\n", badcount, m->name);	badcount = 0;      }    }  }  last = now;  strcpy(buf, "");  for(i = 0; i < sizeof(m->backbuf); i++) {    int byte = m->backbuf[(m->backbuf_idx + i) % sizeof(m->backbuf)];    sprintf(&buf[i*3], " %02x", byte);  }  fifo_log(m, LOG_DEBUG, "%s on link '%s'. Last raw bits':%s\n", msg, m->name, buf);  mtp2_error_mon_count_frame(m);  mtp2_emon_count_error(m);}/* This MTP2 check bits calculation was nicked from zaptel.c, courtesy of   the GPL.*/#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])static unsigned short fcstab[256] ={	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,

⌨️ 快捷键说明

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