chan_h323.c

来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C语言 代码 · 共 2,305 行 · 第 1/5 页

C
2,305
字号
   int oldformat;   if(gH323Debug)      ast_verbose("---   ooh323_request - data %s format %s\n", (char*)data,                                ast_getformatname_multiple(formats,512,format) );   oldformat = format;   format &= ((AST_FORMAT_MAX_AUDIO << 1) - 1);   if (!format) {      ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format "                          "'%d'\n", format);      return NULL;   }   p = ooh323_alloc(0,0); /* Initial callRef is zero */   if(!p)   {      ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char*)data);      return NULL;   }   ast_mutex_lock(&p->lock);   /* This is an outgoing call, since ooh323_request is called */   ast_set_flag(p, H323_OUTGOING);   strncpy(tmp, (char*)data, sizeof(tmp)-1);   dest = strchr(tmp, '/');   if(dest)   {        *dest = '\0';      dest++;      ext = tmp;   }else if((dest = strchr(tmp, '@'))){      *dest = '\0';      dest++;      ext = tmp;   }else{      dest = tmp;      ext = NULL;   }   if(dest)      peer = find_peer(dest);   else{      ast_log(LOG_ERROR, "Destination format is not supported\n");      return NULL;   }   if(peer)   {      p->username = strdup(peer->name);      p->host = strdup(peer->ip);      p->port = peer->port;      /* Disable gk as we are going to call a known peer*/      OO_SETFLAG(p->flags, H323_DISABLEGK);      if(ext)         strncpy(p->exten, ext, sizeof(p->exten)-1);      if(peer->capability & format)         p->capability = peer->capability & format;      else{        p->capability = peer->capability;      }      memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref));      p->dtmfmode = peer->dtmfmode;      strncpy(p->accountcode, peer->accountcode, sizeof(p->accountcode)-1);      p->amaflags = peer->amaflags;   }else {      p->dtmfmode = gDTMFMode;      p->capability = gCapability;      memcpy(&p->prefs, &gPrefs, sizeof(struct ast_codec_pref));      p->username = strdup(dest);           p->host = strdup(dest);      if(ext)         strncpy(p->exten, ext, sizeof(p->exten)-1);   }   chan = ooh323_new(p, AST_STATE_DOWN, p->username);      ast_mutex_unlock(&p->lock);   if (!chan)   {      ast_mutex_lock(&iflock);      ooh323_destroy(p);      ast_mutex_unlock(&iflock);   }	   restart_monitor();   if(gH323Debug)      ast_verbose("+++   ooh323_request\n");   return chan;}static struct ooh323_pvt* find_call(ooCallData *call){   struct ooh323_pvt *p=NULL;   if(gH323Debug)      ast_verbose("---   find_call\n");   p = iflist;   ast_mutex_lock(&iflock);   while(p)   {      if(p->callToken && !strcmp(p->callToken, call->callToken))      {         break;      }      p = p->next;         }   ast_mutex_unlock(&iflock);   if(gH323Debug)      ast_verbose("+++   find_call\n");   return p;}struct ooh323_user *find_user(const char * name){   struct ooh323_user *user=NULL;   if(gH323Debug)      ast_verbose("---   find_user\n");   user = userl.users;   ast_mutex_lock(&userl.lock);   while(user)   {      if(name && !strcmp(user->name, name))         break;      user = user->next;   }   ast_mutex_unlock(&userl.lock);   if(gH323Debug)      ast_verbose("+++   find_user\n");   return user;      }struct ooh323_peer *find_peer(const char * name){   struct ooh323_peer *peer=NULL;   if(gH323Debug)      ast_verbose("---   find_peer\n");   peer = peerl.peers;   ast_mutex_lock(&peerl.lock);   while(peer)   {      if(!strcasecmp(peer->name, name))         break;      if(peer->h323id && !strcasecmp(peer->h323id, name))         break;      if(peer->e164 && !strcasecmp(peer->e164, name))         break;      peer = peer->next;   }   ast_mutex_unlock(&peerl.lock);   if(gH323Debug)      ast_verbose("+++   find_peer\n");   return peer;      }static int ooh323_digit(struct ast_channel *chan, char digit){   char dtmf[2];   struct ooh323_pvt *p = (struct ooh323_pvt *) chan->tech_pvt;      if(gH323Debug)      ast_verbose("---   ooh323_digit\n");   if(!p){      ast_log(LOG_ERROR, "No private structure for call\n");      return -1;   }   ast_mutex_lock(&p->lock);   if (p->rtp && (p->dtmfmode & H323_DTMF_RFC2833)) {      ast_rtp_senddigit(p->rtp, digit);   }else if (((p->dtmfmode & H323_DTMF_Q931) ||                   (p->dtmfmode & H323_DTMF_H245ALPHANUMERIC) ||                   (p->dtmfmode & H323_DTMF_H245SIGNAL))){      dtmf[0]= digit;      dtmf[1]='\0';      ast_mutex_lock(&ooh323c_cmd_lock);      ooSendDTMFDigit(p->callToken, dtmf);      ast_mutex_unlock(&ooh323c_cmd_lock);   }   ast_mutex_unlock(&p->lock);   if(gH323Debug)      ast_verbose("+++   ooh323_digit\n");   return 0;}static int ooh323_call(struct ast_channel *ast, char *dest, int timeout){   struct ooh323_pvt *p = ast->tech_pvt;   char destination[256];   int res=0;   char *val=NULL;   ooCallOptions opts = {      .fastStart = TRUE,      .tunneling = TRUE,      .disableGk = TRUE,      .callMode = OO_CALLMODE_AUDIOCALL   };   if(gH323Debug)      ast_verbose("---   ooh323_call- %s\n", dest);   if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED))    {      ast_log(LOG_WARNING, "ooh323_call called on %s, neither down nor "                           "reserved\n", ast->name);      return -1;   }   ast_mutex_lock(&p->lock);   ast_set_flag(p, H323_OUTGOING);   if (ast->cid.cid_num) {     if(p->callerid_num)   free(p->callerid_num);      p->callerid_num = strdup(ast->cid.cid_num);   }   if(ast->cid.cid_name) {      if(p->callerid_name)   free(p->callerid_name);      p->callerid_name = strdup(ast->cid.cid_name);   }else{      ast->cid.cid_name = strdup(gCallerID);      if(p->callerid_name)   free(p->callerid_name);      p->callerid_name = strdup(ast->cid.cid_name);   }   /* Retrieve vars */   val = pbx_builtin_getvar_helper(ast, "CALLER_H323ID");   if(val){     strncpy(p->caller_h323id, val, sizeof(p->caller_h323id)-1);   }      val = pbx_builtin_getvar_helper(ast, "CALLER_H323DIALEDDIGITS");   if(val){      strncpy(p->caller_dialedDigits, val, sizeof(p->caller_dialedDigits)-1);      if(!p->callerid_num)   p->callerid_num = strdup(val);        }   val = pbx_builtin_getvar_helper(ast, "CALLER_H323EMAIL");   if(val)     strncpy(p->caller_email, val, sizeof(p->caller_email)-1);      val = pbx_builtin_getvar_helper(ast, "CALLER_H323URL");   if(val)     strncpy(p->caller_url, val, sizeof(p->caller_url)-1);     p->callToken = (char*)malloc(AST_MAX_EXTENSION);   if(!p->callToken)   {      ast_mutex_unlock(&p->lock);      ast_log(LOG_ERROR, "Failed to allocate memory for callToken\n");      return -1; /* TODO: need to clean/hangup?? */   }         if(p->host && p->port != 0)      sprintf(destination, "%s:%d", p->host, p->port);   else if(p->host)      sprintf(destination, "%s", p->host);   else     strncpy(destination, dest, sizeof(destination)-1);   destination[sizeof(destination)-1]='\0';   ast_mutex_lock(&ooh323c_cmd_lock);   if(OO_TESTFLAG(p->flags, H323_DISABLEGK))      res = ooMakeCall(destination, p->callToken, AST_MAX_EXTENSION, &opts);   else      res = ooMakeCall(destination, p->callToken, AST_MAX_EXTENSION, NULL);   ast_mutex_unlock(&ooh323c_cmd_lock);   ast_mutex_unlock(&p->lock);   if(res != OO_OK)   {      ast_log(LOG_ERROR,"Failed to make call\n");      return -1; /* ToDO: cleanup */   }   if(gH323Debug)      ast_verbose("+++   ooh323_call\n");  return 0;}static int ooh323_hangup(struct ast_channel *ast){   struct ooh323_pvt *p = ast->tech_pvt;   if(gH323Debug)      ast_verbose("---   ooh323_hangup\n");   if(p)   {      ast_mutex_lock(&p->lock);      if(gH323Debug)         ast_verbose("    hanging %s\n", p->username);      if(!ast_test_flag(p, H323_ALREADYGONE))      {         ast_mutex_lock(&ooh323c_cmd_lock);         ooHangCall(p->callToken,              ooh323_convert_hangupcause_asteriskToH323(p->owner->hangupcause));         ast_mutex_unlock(&ooh323c_cmd_lock);         ast_set_flag(p, H323_ALREADYGONE);	 //         ast_mutex_unlock(&p->lock);      }else {         ast_set_flag(p, H323_NEEDDESTROY);      }      /* detach channel here */      if(p->owner)      {         p->owner->tech_pvt = NULL;         p->owner = NULL;      }     ast_mutex_unlock(&p->lock);     ast_mutex_lock(&usecnt_lock);     usecnt--;     ast_mutex_unlock(&usecnt_lock);        /* Notify the module monitors that use count for resource has changed*/     ast_update_use_count();        }else{      ast_log(LOG_ERROR, "No call to hangup\n" );      return -1;   }   if(gH323Debug)      ast_verbose("+++   ooh323_hangup\n");  return 0;}static int ooh323_answer(struct ast_channel *ast){   struct ooh323_pvt *p = ast->tech_pvt;   if(gH323Debug)      ast_verbose("--- ooh323_answer\n");   ast_mutex_lock(&p->lock);   if(ast->_state != AST_STATE_UP)   {      ast_mutex_lock(&ast->lock);      ast_setstate(ast, AST_STATE_UP);      if (option_debug)         ast_log(LOG_DEBUG, "ooh323_answer(%s)\n", ast->name);      ast_mutex_unlock(&ast->lock);      ast_mutex_lock(&ooh323c_cmd_lock);      ooAnswerCall(p->callToken);      ast_mutex_unlock(&ooh323c_cmd_lock);   }   ast_mutex_unlock(&p->lock);   if(gH323Debug)      ast_verbose("+++ ooh323_answer\n");  return 0;}static struct ast_frame *ooh323_read(struct ast_channel *ast){   struct ast_frame *fr;   static struct ast_frame null_frame = { AST_FRAME_NULL, };   struct ooh323_pvt *p = ast->tech_pvt;   ast_mutex_lock(&p->lock);   if(p->rtp)      fr = ooh323_rtp_read(ast, p);   else      fr = &null_frame;   //   time(&p->lastrtprx);   ast_mutex_unlock(&p->lock);   return fr;}static int ooh323_write(struct ast_channel *ast, struct ast_frame *f){   struct ooh323_pvt *p = ast->tech_pvt;   int res = 0;   if(f->frametype == AST_FRAME_VOICE)   {      if(!(f->subclass & ast->nativeformats))      {         ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native "                             "formats is %d (read/write = %d/%d)\n",                           f->subclass, ast->nativeformats, ast->readformat,                              ast->writeformat);         return 0;      }      if(p){         ast_mutex_lock(&p->lock);         if(p->rtp)            res = ast_rtp_write(p->rtp, f);         ast_mutex_unlock(&p->lock);      }   } else if (f->frametype == AST_FRAME_IMAGE) {      return 0;   } else {      ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n",                             f->frametype);      return 0;   }   return res;}static int ooh323_indicate(struct ast_channel *ast, int condition){   struct ooh323_pvt *p = (struct ooh323_pvt *) ast->tech_pvt;   char *callToken = (char *)NULL;   ast_mutex_lock(&p->lock);   callToken = (p->callToken ? strdup(p->callToken) : NULL);   ast_mutex_unlock(&p->lock);   if(!callToken)   {      if(gH323Debug)         ast_verbose("   ooh323_indicate - No callToken\n");      return -1;   }   if(gH323Debug)      ast_verbose("----- ooh323_indicate %d on call %s\n", condition, callToken);       switch(condition) {

⌨️ 快捷键说明

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