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 + -
显示快捷键?