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

📄 l4isup.c

📁 asterisk 中国七号驱动修改代码可以在ASTERISIK-1。4上编译pa
💻 C
📖 第 1 页 / 共 5 页
字号:
  struct ss7_chan *prev, *cur;  cur = linkset->idle_list;  prev = NULL;  while(cur != NULL) {    if(pvt->cic == cur->cic) {      if(prev == NULL) {        linkset->idle_list = pvt->next_idle;      } else {        prev->next_idle = pvt->next_idle;      }      pvt->next_idle = NULL;      return;    }    prev = cur;    cur = cur->next_idle;  }  ast_log(LOG_NOTICE, "Trying to remove CIC=%d from idle list, but not "          "found?!?.\n", pvt->cic);}/* This function must be called with the global lock mutex held. */static void add_to_idlelist(struct ss7_chan *pvt) {  struct linkset* linkset = pvt->link->linkset;  struct ss7_chan *prev, *cur;#if 1  cur = linkset->idle_list;  prev = NULL;  while(cur != NULL) {    if(pvt->cic == cur->cic) {      ast_log(LOG_NOTICE, "Trying to add CIC=%d to idle list, but already there?!?\n", pvt->cic);      return;    }    cur = cur->next_idle;  }#endif  pvt->next_idle = linkset->idle_list;  linkset->idle_list = pvt;}/* This implements hunting policy. It must be called with the global lock mutex   held. *//* This implements the policy: Primary hunting group odd CICs, secondary   hunting group even CICs. Choose least recently used CIC. */static struct ss7_chan *cic_hunt_odd_lru(struct linkset* linkset) {  struct ss7_chan *cur, *prev, *best, *best_prev;  int odd;  best = NULL;  best_prev = NULL;  for(odd = 1; odd >= 0; odd--) {    for(cur = linkset->idle_list, prev = NULL; cur != NULL; prev = cur, cur = cur->next_idle) {      /* Don't select lines that are resetting or blocked. */      if(!cur->reset_done || (cur->blocked & (BL_LH|BL_RM|BL_RH|BL_UNEQUIPPED|BL_LINKDOWN))) {        continue;      }      if((cur->cic % 2) == odd) {        best = cur;        best_prev = prev;      }    }    if(best != NULL) {      if(best_prev == NULL) {        linkset->idle_list = best->next_idle;      } else {        best_prev->next_idle = best->next_idle;      }      best->next_idle = NULL;      return best;    }  }  ast_log(LOG_WARNING, "No idle circuit found.\n");  return NULL;}/* This implements the policy: Primary hunting group even CICs, secondary   hunting group odd CICs. Choose most recently used CIC. */static struct ss7_chan *cic_hunt_even_mru(struct linkset* linkset) {  struct ss7_chan *cur, *prev, *best, *best_prev;  best = NULL;  best_prev = NULL;  for(cur = linkset->idle_list, prev = NULL; cur != NULL; prev = cur, cur = cur->next_idle) {    /* Don't select lines that are resetting or blocked. */    if(!cur->reset_done || (cur->blocked & (BL_LH|BL_RM|BL_RH|BL_UNEQUIPPED|BL_LINKDOWN))) {      continue;    }    if((cur->cic % 2) == 0) {      /* Choose the first idle even circuit, if any. */      best = cur;      best_prev = prev;      break;    } else if(best == NULL) {      /* Remember the first odd circuit, in case no even circuits are         available. */      best = cur;      best_prev = prev;    }  }  if(best != NULL) {    if(best_prev == NULL) {      linkset->idle_list = best->next_idle;    } else {      best_prev->next_idle = best->next_idle;    }    best->next_idle = NULL;    return best;  } else {    ast_log(LOG_WARNING, "No idle circuit found.\n");    return NULL;  }}/* This implements the policy: Sequential low to high CICs */static struct ss7_chan *cic_hunt_seq_lth_htl(struct linkset* linkset, int lth){  struct ss7_chan *cur, *prev, *best = NULL, *best_prev = NULL;  for(cur = linkset->idle_list, prev = NULL; cur != NULL; prev = cur, cur = cur->next_idle) {    /* Don't select lines that are resetting or blocked. */    if(!cur->reset_done || (cur->blocked & (BL_LH|BL_RM|BL_RH|BL_UNEQUIPPED|BL_LINKDOWN))) {      continue;    }    if (!best) {      best = cur;      continue;    }    if (lth) {      if (cur->cic < best->cic) {	best = cur;	best_prev = prev;      }    }    else {      if (cur->cic > best->cic) {	best = cur;	best_prev = prev;      }    }  }  if(best != NULL) {    if(best_prev == NULL) {      linkset->idle_list = best->next_idle;    } else {      best_prev->next_idle = best->next_idle;    }    best->next_idle = NULL;    return best;  } else {    ast_log(LOG_WARNING, "No idle circuit found.\n");    return NULL;  }}/* Send a "release" message. */static void isup_send_rel(struct ss7_chan *pvt, int cause) {  unsigned char msg[MTP_MAX_PCK_SIZE];  int current, varptr;  unsigned char param[2];  isup_msg_init(msg, sizeof(msg), this_host->opc, peerpc(pvt), pvt->cic, ISUP_REL, &current);  isup_msg_start_variable_part(msg, sizeof(msg), &varptr, &current, 1, 1);  param[0] = 0x85;              /* Last octet, ITU-T coding, private network */  param[1] = 0x80 | (cause & 0x7f); /* Last octet */  isup_msg_add_variable(msg, sizeof(msg), &varptr, &current, param, 2);  isup_msg_start_optional_part(msg, sizeof(msg), &varptr, &current);  isup_msg_end_optional_part(msg, sizeof(msg), &current);  mtp_enqueue_isup(pvt, msg, current);}/* Send a "release confirmed" message. */static void isup_send_rlc(struct ss7_chan* pvt) {  unsigned char msg[MTP_MAX_PCK_SIZE];  int current, varptr;  int cic = pvt->cic;  isup_msg_init(msg, sizeof(msg), this_host->opc, peerpc(pvt), cic, ISUP_RLC, &current);  isup_msg_start_variable_part(msg, sizeof(msg), &varptr, &current, 0, 1);  isup_msg_start_optional_part(msg, sizeof(msg), &varptr, &current);  isup_msg_end_optional_part(msg, sizeof(msg), &current);  mtp_enqueue_isup(pvt, msg, current);}/* Send a "reset circuit" message. */static void isup_send_rsc(struct ss7_chan* pvt) {  unsigned char msg[MTP_MAX_PCK_SIZE];  int current, varptr;  int cic = pvt->cic;  isup_msg_init(msg, sizeof(msg), this_host->opc, peerpc(pvt), cic, ISUP_RSC, &current);  isup_msg_start_variable_part(msg, sizeof(msg), &varptr, &current, 0, 0);  mtp_enqueue_isup(pvt, msg, current);}/* Send an "address complete" message. */static void isup_send_acm(struct ss7_chan* pvt) {  unsigned char msg[MTP_MAX_PCK_SIZE];  int current, varptr;  unsigned char param[2];  int cic = pvt->cic;  isup_msg_init(msg, sizeof(msg), this_host->opc, peerpc(pvt), cic, ISUP_ACM, &current);  param[0] = 0x12;  param[1] = 0x14;	     isup_msg_add_fixed(msg, sizeof(msg), &current, param, 2);  if (pvt->has_inband_ind) {    unsigned char param_opt_backw_ind[1];    param_opt_backw_ind[0] = 0x01;    isup_msg_start_variable_part(msg, sizeof(msg), &varptr, &current, 0, 1);    isup_msg_start_optional_part(msg, sizeof(msg), &varptr, &current);    isup_msg_add_optional(msg, sizeof(msg), &current, IP_OPTIONAL_BACKWARD_CALL_INDICATORS,			  param_opt_backw_ind, 1);    isup_msg_end_optional_part(msg, sizeof(msg), &current);  }  else {    isup_msg_start_variable_part(msg, sizeof(msg), &varptr, &current, 0, 1);  }  mtp_enqueue_isup(pvt, msg, current);}/* Send a "circuit group blocking" message. */static void isup_send_cgb(struct ss7_chan* pvt, int mask) {  int sup_type_ind = 0x00; /* Maintenance oriented supervision message type */  int cic = pvt->cic;  if (pvt->equipped)    sup_type_ind = 0x00; /* Maintenance oriented supervision message type */  else    sup_type_ind = 0x01; /* Hardware failure oriented */  do_group_circuit_block_unblock(pvt->link->linkset, cic, mask, sup_type_ind, 0, 0, 1);}/* Send a "circuit group unblocking" message. */static void isup_send_cgu(struct ss7_chan* pvt, int mask) {  int sup_type_ind = 0x00; /* Maintenance oriented supervision message type */  int cic = pvt->cic;  if (pvt->equipped)    sup_type_ind = 0x00; /* Maintenance oriented supervision message type */  else    sup_type_ind = 0x01; /* Hardware failure oriented */  do_group_circuit_block_unblock(pvt->link->linkset, cic, mask, sup_type_ind, 0, 0, 0);}/* Send a "blocked" message. */static void isup_send_blk(struct ss7_chan *pvt){  unsigned char msg[MTP_MAX_PCK_SIZE];  int current, varptr;    isup_msg_init(msg, sizeof(msg), this_host->opc, peerpc(pvt), pvt->cic, ISUP_BLK, &current);  isup_msg_start_variable_part(msg, sizeof(msg), &varptr, &current, 0, 0);  mtp_enqueue_isup(pvt, msg, current);}/* Reset circuit. Called with pvt->lock held */static void reset_circuit(struct ss7_chan* pvt){  isup_send_rsc(pvt);  t16_start(pvt);}/* Initiate release circuit. Called with pvt->lock held */static void initiate_release_circuit(struct ss7_chan* pvt, int cause){  pvt->hangupcause = cause; /* Remember for REL retransmit */  /* We sometimes get hangupcause=0 (seen when no match in dialplan, not     even invalid handler). This doesn't work too well, for example     ast_softhangup() doesn't actually hang up when hangupcause=0. */  if(pvt->hangupcause == 0) {    pvt->hangupcause = AST_CAUSE_NORMAL_CLEARING;  }  isup_send_rel(pvt, pvt->hangupcause);  pvt->state = ST_SENT_REL;  /* Set up timer T1 and T5 waiting for RLC. */  t1_start(pvt);  t5_start(pvt);}/* Setup a new channel, for an incoming or an outgoing call.   Assumes called with global lock and pvt->lock held. */static struct ast_channel *ss7_new(struct ss7_chan *pvt, int state, char* cid_num, char* exten) {  struct ast_channel *chan;#ifdef USE_ASTERISK_1_2  chan = ast_channel_alloc(1);  if(!chan) {    return NULL;  }  snprintf(chan->name, sizeof(chan->name), "%s/%s/%d", type, pvt->link->linkset->name, pvt->cic);  chan->type = type;#else  chan = ast_channel_alloc(1, state, cid_num, NULL, NULL, exten, pvt->context, 0, "%s/%s/%d", type, pvt->link->linkset->name, pvt->cic);  ast_jb_configure(chan, ss7_get_global_jbconf());  if(!chan) {    return NULL;  }#endif  chan->tech = &ss7_tech;  chan->nativeformats = AST_FORMAT_ALAW;  chan->rawreadformat = AST_FORMAT_ALAW;  chan->rawwriteformat = AST_FORMAT_ALAW;  ast_setstate(chan, state);  chan->fds[0] = pvt->zaptel_fd;  chan->tech_pvt = pvt;  pvt->owner = chan;  incr_usecount();  flushchannel(pvt->zaptel_fd, pvt->cic);  pvt->lastread.tv_sec = pvt->lastread.tv_usec = 0;  return chan;}/* hunt free CIC */static struct ss7_chan* cic_hunt(struct linkset* linkset){  struct ss7_chan* pvt;  switch(linkset->hunt_policy) {  case HUNT_ODD_LRU:    pvt = cic_hunt_odd_lru(linkset);    break;  case HUNT_EVEN_MRU:    pvt = cic_hunt_even_mru(linkset);    break;  case HUNT_SEQ_LTH:    pvt = cic_hunt_seq_lth_htl(linkset, 1);    break;  case HUNT_SEQ_HTL:    pvt = cic_hunt_seq_lth_htl(linkset, 0);    break;  default:    pvt = NULL;    ast_log(LOG_ERROR, "Internal error: invalid hunting policy %d.\n",	    linkset->hunt_policy);  }  return pvt;}/* Request an SS7 channel. */static struct ast_channel *ss7_requester(const char *type, int format,                                         void *data, int *cause) {  char *arg = data;  struct ast_channel *chan;  struct ss7_chan *pvt;  struct linkset* linkset = this_host->default_linkset;  char *sep = strchr(arg, '/');  ast_log(LOG_DEBUG, "SS7 request (%s/%s) format = 0x%X.\n", type, arg, format);  if(format != AST_FORMAT_ALAW) {    ast_log(LOG_NOTICE, "Audio format 0x%X not supported by SS7 channel.\n",            format);    return NULL;  }  if (sep) {    char name_buf[100];    strncpy(name_buf, arg, sep-arg);    name_buf[sep-arg] = 0;    linkset = lookup_linkset(name_buf);    if (!linkset) {      ast_log(LOG_ERROR, "SS7 requester: No such linkset: '%s', using default\n", name_buf);      linkset = this_host->default_linkset;    }  }  lock_global();  pvt = cic_hunt(linkset);  if(pvt == NULL) {    unlock_global();    *cause = AST_CAUSE_CONGESTION;    ast_log(LOG_WARNING, "SS7 requester: No idle circuit available.\n");    return NULL;  }  ast_mutex_lock(&pvt->lock);  chan = ss7_new(pvt, AST_STATE_DOWN, NULL, sep ? sep+1 : arg);  if(!chan) {    ast_mutex_unlock(&pvt->lock);    unlock_global();    *cause = AST_CAUSE_CONGESTION;    ast_log(LOG_WARNING, "Unable to allocate SS7 channel structure.\n");    return NULL;  }  ast_mutex_unlock(&pvt->lock);  unlock_global();  ast_update_use_count();  ast_log(LOG_DEBUG, "SS7 channel %s/%s allocated successfully.\n", type, arg);  return chan;}static int ss7_send_digit_begin(struct ast_channel *chan, char digit) {  struct ss7_chan *pvt = chan->tech_pvt;  ast_mutex_lock(&pvt->lock);  if (!io_send_dtmf(pvt->zaptel_fd, pvt->cic, digit))    pvt->sending_dtmf = 1;  ast_mutex_unlock(&pvt->lock);  return 0;}static int ss7_send_digit_end(struct ast_channel *chan, char digit, unsigned int duration) {  return 0;}static void ss7_send_call_progress(struct ss7_chan *pvt, int value) {  unsigned char msg[MTP_MAX_PCK_SIZE];  int current, varptr;  unsigned char param[1];  unsigned char param_backward_ind[2];  unsigned char param_opt_backw_ind[1];  isup_msg_init(msg, sizeof(msg), this_host->opc, peerpc(pvt), pvt->cic, ISUP_CPR, &current);  param[0] = value;              /* Event information */

⌨️ 快捷键说明

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