Newer
Older
int reloading;
struct ooh323_pvt *h323 = NULL;
time_t t;
for (;;) {
struct ooh323_pvt *h323_next;
/* Check for a reload request */
ast_mutex_lock(&h323_reload_lock);
reloading = h323_reloading;
h323_reloading = 0;
ast_mutex_unlock(&h323_reload_lock);
if (reloading) {
ast_verb(1, "Reloading H.323\n");
ooh323_do_reload();
}
if (gH323ep.gkClient && gH323ep.gkClient->state == GkClientStopped) {
ooGkClientDestroy();
ast_verb(0, "Restart stopped gatekeeper client\n");
ooGkClientInit(gRasGkMode, (gRasGkMode == RasUseSpecificGatekeeper) ?
gGatekeeper : 0, gRASIP, 0);
ooGkClientStart(gH323ep.gkClient);
}
/* Check for interfaces needing to be killed */
ast_mutex_lock(&iflock);
time(&t);
h323 = iflist;
while (h323) {
h323_next = h323->next;
if (h323->rtp && h323->rtptimeout && h323->lastrtptx &&
h323->lastrtptx + h323->rtptimeout < t) {
ast_rtp_instance_sendcng(h323->rtp, 0);
h323->lastrtptx = time(NULL);
}
if (h323->rtp && h323->owner && h323->rtptimeout &&
h323->lastrtprx && ast_sockaddr_isnull(&h323->redirip) &&
h323->lastrtprx + h323->rtptimeout < t) {
if (!ast_channel_trylock(h323->owner)) {
ast_softhangup_nolock(h323->owner, AST_SOFTHANGUP_DEV);
ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", ast_channel_name(h323->owner), (long) (t - h323->lastrtprx));
ast_channel_unlock(h323->owner);
}
if (ast_test_flag(h323, H323_NEEDDESTROY)) {
ooh323_destroy (h323);
} /* else if (ast_test_flag(h323, H323_NEEDSTART) && h323->owner) {
ast_channel_lock(h323->owner);
if (ast_pbx_start(h323->owner)) {
ast_log(LOG_WARNING, "Unable to start PBX on %s\n", h323->owner->name);
ast_channel_unlock(h323->owner);
ast_hangup(h323->owner);
}
ast_channel_unlock(h323->owner);
ast_clear_flag(h323, H323_NEEDSTART);
} */
h323 = h323_next;
}
ast_mutex_unlock(&iflock);
pthread_testcancel();
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
/* Wait for sched or io */
res = ast_sched_wait(sched);
if ((res < 0) || (res > 1000)) {
res = 1000;
}
res = ast_io_wait(io, res);
pthread_testcancel();
ast_mutex_lock(&monlock);
if (res >= 0) {
ast_sched_runq(sched);
}
ast_mutex_unlock(&monlock);
}
/* Never reached */
return NULL;
}
int restart_monitor(void)
{
pthread_attr_t attr;
/* If we're supposed to be stopped -- stay stopped */
if (monitor_thread == AST_PTHREADT_STOP)
return 0;
if (ast_mutex_lock(&monlock)) {
ast_log(LOG_WARNING, "Unable to lock monitor\n");
return -1;
}
if (monitor_thread == pthread_self()) {
ast_mutex_unlock(&monlock);
ast_log(LOG_WARNING, "Cannot kill myself\n");
return -1;
}
if (monitor_thread != AST_PTHREADT_NULL) {
/* Wake up the thread */
pthread_kill(monitor_thread, SIGURG);
} else {
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
/* Start a new monitor */
if (ast_pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
ast_mutex_unlock(&monlock);
ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
return -1;
}
}
ast_mutex_unlock(&monlock);
return 0;
}
int ooh323_destroy(struct ooh323_pvt *p)
{
/* NOTE: Assumes iflock already acquired */
struct ooh323_pvt *prev = NULL, *cur = NULL;
struct ooh323_user *user = NULL;
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, "--- ooh323_destroy \n");
if (p)
Tilghman Lesher
committed
ast_verb(0, " Destroying %s\n", p->username);
}
cur = iflist;
while (cur) {
if (cur == p) { break; }
prev = cur;
cur = cur->next;
}
if (cur) {
ast_mutex_lock(&cur->lock);
if (prev)
prev->next = cur->next;
else
iflist = cur->next;
if (cur->callToken) {
Tilghman Lesher
committed
ast_verb(0, " Destroying %s\n", cur->callToken);
cur->callToken = 0;
}
if (cur->username) {
ast_free(cur->username);
cur->username = 0;
}
if (cur->host) {
ast_free(cur->host);
cur->host = 0;
}
if (cur->callerid_name) {
ast_free(cur->callerid_name);
cur->callerid_name = 0;
}
if (cur->callerid_num) {
ast_free(cur->callerid_num);
cur->callerid_num = 0;
}
if (cur->rtp) {
ast_rtp_instance_stop(cur->rtp);
ast_rtp_instance_destroy(cur->rtp);
cur->rtp = NULL;
}
if (cur->udptl) {
ast_udptl_destroy(cur->udptl);
cur->udptl = NULL;
/* Unlink us from the owner if we have one */
if (cur->owner) {
while(ast_channel_trylock(cur->owner)) {
ast_debug(1, "Failed to grab lock, trying again\n");
ast_debug(1, "Detaching from %s\n", ast_channel_name(cur->owner));
ast_channel_tech_pvt_set(cur->owner, NULL);
ast_channel_unlock(cur->owner);
cur->owner = NULL;
if (cur->vad) {
ast_dsp_free(cur->vad);
cur->vad = NULL;
}
/* decrement user/peer count */
if(!ast_test_flag(cur, H323_OUTGOING)) {
if (cur->neighbor.user) {
user = find_user(p->callerid_name, cur->neighbor.user);
if(user && user->inUse > 0) {
ast_mutex_lock(&user->lock);
user->inUse--;
ast_mutex_unlock(&user->lock);
}
ast_free(cur->neighbor.user);
}
} else {
/* outgoing limit decrement here !!! */
}
ast_mutex_unlock(&cur->lock);
ast_mutex_destroy(&cur->lock);
ao2_cleanup(cur->writeformat);
ao2_cleanup(cur->readformat);
ao2_cleanup(cur->cap);
}
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ ooh323_destroy\n");
return 0;
}
int delete_peers()
{
struct ooh323_peer *cur = NULL, *prev = NULL;
ast_mutex_lock(&peerl.lock);
cur = peerl.peers;
while (cur) {
prev = cur;
cur = cur->next;
ast_mutex_destroy(&prev->lock);
ast_free(prev->h323id);
ast_free(prev->email);
ast_free(prev->url);
ast_free(prev->e164);
if(prev->rtpmask) {
ast_mutex_lock(&prev->rtpmask->lock);
prev->rtpmask->inuse--;
ast_mutex_unlock(&prev->rtpmask->lock);
if (prev->rtpmask->inuse == 0) {
regfree(&prev->rtpmask->regex);
ast_mutex_destroy(&prev->rtpmask->lock);
ast_free(prev->rtpmask);
ast_free(prev);
if (cur == peerl.peers) {
break;
}
}
peerl.peers = NULL;
ast_mutex_unlock(&peerl.lock);
return 0;
}
int delete_users()
{
struct ooh323_user *cur = NULL, *prev = NULL;
ast_mutex_lock(&userl.lock);
cur = userl.users;
while (cur) {
prev = cur;
cur = cur->next;
ast_mutex_destroy(&prev->lock);
if(prev->rtpmask) {
ast_mutex_lock(&prev->rtpmask->lock);
prev->rtpmask->inuse--;
ast_mutex_unlock(&prev->rtpmask->lock);
if (prev->rtpmask->inuse == 0) {
regfree(&prev->rtpmask->regex);
ast_mutex_destroy(&prev->rtpmask->lock);
ast_free(prev->rtpmask);
ao2_cleanup(prev->cap);
ast_free(prev);
if (cur == userl.users) {
break;
}
}
userl.users = NULL;
ast_mutex_unlock(&userl.lock);
return 0;
}
static int unload_module(void)
{
struct ooh323_pvt *p;
struct ooAliases *cur = NULL, *prev = NULL;
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, "--- ooh323 unload_module \n");
}
/* First, take us out of the channel loop */
ast_cli_unregister_multiple(cli_ooh323, sizeof(cli_ooh323) / sizeof(struct ast_cli_entry));
ast_rtp_glue_unregister(&ooh323_rtp);
ast_channel_unregister(&ooh323_tech);
#if 0
ast_unregister_atexit(&ast_ooh323c_exit);
#endif
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, " unload_module - hanging up all interfaces\n");
}
if (!ast_mutex_lock(&iflock)) {
/* Hangup all interfaces if they have an owner */
p = iflist;
while (p) {
if (p->owner) {
ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
}
p = p->next;
}
iflist = NULL;
ast_mutex_unlock(&iflock);
} else {
ast_log(LOG_WARNING, "Unable to lock the interface list\n");
return -1;
}
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, " unload_module - stopping monitor thread\n");
if (monitor_thread != AST_PTHREADT_NULL) {
if (!ast_mutex_lock(&monlock)) {
if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
pthread_cancel(monitor_thread);
pthread_kill(monitor_thread, SIGURG);
pthread_join(monitor_thread, NULL);
}
monitor_thread = AST_PTHREADT_STOP;
ast_mutex_unlock(&monlock);
} else {
ast_log(LOG_WARNING, "Unable to lock the monitor\n");
return -1;
}
}
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, " unload_module - stopping stack thread\n");
}
ooh323c_stop_stack_thread();
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, " unload_module - freeing up memory used by interfaces\n");
}
if (!ast_mutex_lock(&iflock)) {
struct ooh323_pvt *pl;
/* Destroy all the interfaces and free their memory */
p = iflist;
while (p) {
pl = p;
p = p->next;
/* Free associated memory */
ooh323_destroy(pl);
}
iflist = NULL;
ast_mutex_unlock(&iflock);
} else {
ast_log(LOG_WARNING, "Unable to lock the interface list\n");
return -1;
}
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, " unload_module - deleting users\n");
}
delete_users();
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, " unload_module - deleting peers\n");
}
delete_peers();
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, " unload_module - Freeing up alias list\n");
}
cur = gAliasList;
while (cur) {
prev = cur;
cur = cur->next;
ast_free(prev->value);
ast_free(prev);
}
gAliasList = NULL;
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, " unload_module- destroying OOH323 endpoint \n");
}
ooH323EpDestroy();
if (gH323Debug) {
Tilghman Lesher
committed
ast_verb(0, "+++ ooh323 unload_module \n");
}
ao2_ref(gCap, -1);
gCap = NULL;
ao2_ref(ooh323_tech.capabilities, -1);
ooh323_tech.capabilities = NULL;
return 0;
}
static void ooh323_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
{
struct ooh323_pvt *p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
if (gH323Debug) {
ast_verb(0, "+++ ooh323 get_codec, %s\n", ast_channel_name(chan));
}
if (p) {
if (ast_format_cap_count(ast_channel_nativeformats(chan))) {
ast_format_cap_append_from_cap(result, ast_channel_nativeformats(chan), AST_MEDIA_TYPE_UNKNOWN);
} else if (ast_format_cap_count(p->cap)) {
ast_format_cap_append_from_cap(result, p->cap, AST_MEDIA_TYPE_UNKNOWN);
}
}
if (gH323Debug) {
ast_verb(0, "--- ooh323 get_codec, %s\n", ast_channel_name(chan));
}
}
static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp)
{
struct ooh323_pvt *p = NULL;
enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
struct ast_sockaddr tmp;
if (gH323Debug) {
ast_verb(0, "+++ ooh323 get_rtp_peer \n");
}
if (!(p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan)))
if (!(p->rtp)) {
return AST_RTP_GLUE_RESULT_FORBID;
*rtp = p->rtp ? ao2_ref(p->rtp, +1), p->rtp : NULL;
/* there must be checking of directmedia setting */
if ((ast_channel_state(chan) != AST_STATE_UP && !p->earlydirect) || !p->directrtp) {
res = AST_RTP_GLUE_RESULT_LOCAL;
} else {
res = AST_RTP_GLUE_RESULT_REMOTE;
}
if (ast_test_flag(&global_jbconf, AST_JB_FORCED)) {
res = AST_RTP_GLUE_RESULT_FORBID;
}
ast_rtp_instance_get_remote_address(*rtp, &tmp);
if (gH323Debug) {
ast_verb(0, "ooh323_get_rtp_peer %s -> %s:%d, %u\n", ast_channel_name(chan), ast_sockaddr_stringify_addr(&tmp),
ast_sockaddr_port(&tmp), res);
}
if (gH323Debug) {
ast_verb(0, "--- ooh323 get_rtp_peer, res = %d\n", (int) res);
}
return res;
}
static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp)
{
struct ooh323_pvt *p = NULL;
enum ast_rtp_glue_result res = AST_RTP_GLUE_RESULT_LOCAL;
if (!(p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan)))
return AST_RTP_GLUE_RESULT_FORBID;
if (!(p->rtp)) {
return AST_RTP_GLUE_RESULT_FORBID;
*rtp = p->vrtp ? ao2_ref(p->vrtp, +1), p->vrtp : NULL;
/* there must check of supporting video per call */
res = AST_RTP_GLUE_RESULT_FORBID;
return res;
}
int ooh323_convertAsteriskCapToH323Cap(struct ast_format *format)
if (ast_format_cmp(format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
return OO_G711ULAW64K;
} else if (ast_format_cmp(format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL) {
return OO_G711ALAW64K;
} else if (ast_format_cmp(format, ast_format_gsm) == AST_FORMAT_CMP_EQUAL) {
return OO_GSMFULLRATE;
} else if (ast_format_cmp(format, ast_format_speex) == AST_FORMAT_CMP_EQUAL) {
} else if (ast_format_cmp(format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {
return OO_G729A;
} else if (ast_format_cmp(format, ast_format_g726) == AST_FORMAT_CMP_EQUAL) {
} else if (ast_format_cmp(format, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) {
} else if (ast_format_cmp(format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {
return OO_G7231;
} else if (ast_format_cmp(format, ast_format_h263) == AST_FORMAT_CMP_EQUAL) {
return OO_H263VIDEO;
} else {
ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_format_get_name(format));
return -1;
}
}
static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp,
struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *cap, int nat_active)
{
/* XXX Deal with Video */
struct ooh323_pvt *p;
int changed = 0;
char *callToken = NULL;
if (gH323Debug) {
ast_verb(0, "--- ooh323_set_peer - %s\n", ast_channel_name(chan));
}
if (ooh323_convertAsteriskCapToH323Cap(ast_channel_writeformat(chan)) < 0) {
ast_log(LOG_WARNING, "Unknown format.\n");
return -1;
}
p = (struct ooh323_pvt *) ast_channel_tech_pvt(chan);
if (!p) {
ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
return -1;
}
ast_mutex_lock(&p->lock);
if (rtp) {
changed |= ast_rtp_instance_get_and_cmp_remote_address(rtp, &p->redirip);
} else if (!ast_sockaddr_isnull(&p->redirip)) {
changed = 1;
memset(&p->redirip, 0, sizeof(p->redirip));
}
callToken = (p->callToken ? ast_strdup(p->callToken) : NULL);
if (!callToken) {
if (gH323Debug) {
ast_verb(0, " set_rtp_peer - No callToken\n");
}
ast_mutex_unlock(&p->lock);
return -1;
}
if (changed) {
if (!ast_sockaddr_isnull(&p->redirip)) {
if (gH323Debug) {
ast_verb(0, "ooh323_set_rtp_peer %s -> %s:%d\n", ast_channel_name(chan), ast_sockaddr_stringify_addr(&p->redirip),
ast_sockaddr_port(&p->redirip));
}
ooUpdateLogChannels(callToken, ast_sockaddr_stringify_addr(&p->redirip),
ast_sockaddr_port(&p->redirip));
} else {
if (gH323Debug) {
ast_verb(0, "ooh323_set_rtp_peer return back to local\n");
}
ooUpdateLogChannels(callToken, "0.0.0.0" , 0);
}
}
ast_mutex_unlock(&p->lock);
ast_free(callToken);
}
int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
{
char lhost[INET6_ADDRSTRLEN];
unsigned lport = 0;
ooMediaInfo mediaInfo;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- configure_local_rtp\n");
memset(&mediaInfo, 0, sizeof(mediaInfo));
if (ast_parse_arg(call->localIP, PARSE_ADDR, &tmp)) {
ast_sockaddr_copy(&tmp, &bindaddr);
}
if (!(p->rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
ast_log(LOG_WARNING, "Unable to create RTP session: %s\n",
strerror(errno));
return 0;
}
ast_rtp_instance_set_qos(p->rtp, gTOS, 0, "ooh323-rtp");
if (!(p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, &tmp))) {
ast_log(LOG_WARNING, "Unable to create UDPTL session: %s\n",
strerror(errno));
return 0;
}
ast_udptl_set_far_max_datagram(p->udptl, 144);
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
if (p->owner) {
while (p->owner && ast_channel_trylock(p->owner)) {
ast_debug(1,"Failed to grab lock, trying again\n");
DEADLOCK_AVOIDANCE(&p->lock);
}
if (!p->owner) {
ast_mutex_unlock(&p->lock);
ast_log(LOG_ERROR, "Channel has no owner\n");
return 0;
}
} else {
ast_log(LOG_ERROR, "Channel has no owner\n");
return 0;
}
ast_channel_set_fd(p->owner, 0, ast_rtp_instance_fd(p->rtp, 0));
ast_channel_set_fd(p->owner, 1, ast_rtp_instance_fd(p->rtp, 1));
ast_channel_set_fd(p->owner, 5, ast_udptl_fd(p->udptl));
ast_channel_unlock(p->owner);
if (p->rtp) {
if (p->cap) {
ast_rtp_codecs_set_framing(ast_rtp_instance_get_codecs(p->rtp),
ast_format_cap_get_framing(p->cap));
}
if (p->nat) {
ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_NAT, 1);
}
if (p->dtmfmode & H323_DTMF_RFC2833 && p->dtmfcodec) {
ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
p->rtp, p->dtmfcodec, "audio", "telephone-event", 0);
}
if (p->dtmfmode & H323_DTMF_CISCO && p->dtmfcodec) {
ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp),
p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
}
/* figure out our local RTP port and tell the H.323 stack about it*/
ast_rtp_instance_get_local_address(p->rtp, &tmp);
ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
lport = ast_sockaddr_port(&tmp);
if (p->rtptimeout) {
ast_rtp_instance_set_timeout(p->rtp, p->rtptimeout);
}
ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1);
}
if (p->rtdrcount) {
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "Setup RTDR info: %d, %d\n", p->rtdrinterval, p->rtdrcount);
call->rtdrInterval = p->rtdrinterval;
call->rtdrCount = p->rtdrcount;
}
ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
mediaInfo.lMediaPort = lport;
mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort + 1;
for (x = 0; x < ast_format_cap_count(p->cap); x++) {
struct ast_format *format = ast_format_cap_get_format(p->cap, x);
strcpy(mediaInfo.dir, "transmit");
mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(format);
ooAddMediaInfo(call, mediaInfo);
strcpy(mediaInfo.dir, "receive");
ooAddMediaInfo(call, mediaInfo);
if (mediaInfo.cap == OO_G729A) {
strcpy(mediaInfo.dir, "transmit");
mediaInfo.cap = OO_G729;
ooAddMediaInfo(call, mediaInfo);
strcpy(mediaInfo.dir, "receive");
ooAddMediaInfo(call, mediaInfo);
strcpy(mediaInfo.dir, "transmit");
mediaInfo.cap = OO_G729B;
ooAddMediaInfo(call, mediaInfo);
strcpy(mediaInfo.dir, "receive");
ooAddMediaInfo(call, mediaInfo);
ao2_ref(format, -1);
}
ast_copy_string(lhost, ast_sockaddr_stringify_addr(&tmp), sizeof(lhost));
lport = ast_sockaddr_port(&tmp);
ast_copy_string(mediaInfo.lMediaIP, lhost, sizeof(mediaInfo.lMediaIP));
mediaInfo.lMediaPort = lport;
mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
mediaInfo.cap = OO_T38;
strcpy(mediaInfo.dir, "transmit");
ooAddMediaInfo(call, mediaInfo);
strcpy(mediaInfo.dir, "receive");
ooAddMediaInfo(call, mediaInfo);
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ configure_local_rtp\n");
return 1;
}
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
void setup_rtp_remote(ooCallData *call, const char *remoteIp, int remotePort)
{
struct ooh323_pvt *p = NULL;
struct ast_sockaddr tmp;
if (gH323Debug) {
ast_verb(0, "--- setup_rtp_remote %s:%d\n", remoteIp, remotePort);
}
if (!remoteIp || !remoteIp[0] || !remotePort) {
if (gH323Debug) {
ast_verb(0, "+++ setup_rtp_remote no data\n");
}
return;
}
/* Find the call or allocate a private structure if call not found */
p = find_call(call);
if (!p || !p->rtp) {
ast_log(LOG_ERROR, "Something is wrong: rtp\n");
return;
}
ast_mutex_lock(&p->lock);
ast_parse_arg(remoteIp, PARSE_ADDR, &tmp);
ast_sockaddr_set_port(&tmp, remotePort);
ast_rtp_instance_set_remote_address(p->rtp, &tmp);
ast_mutex_unlock(&p->lock);
if (gH323Debug) {
ast_verb(0, "+++ setup_rtp_remote\n");
}
return;
}
void setup_rtp_connection(ooCallData *call, const char *remoteIp, int remotePort)
{
struct ooh323_pvt *p = NULL;
if (gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "--- setup_rtp_connection %s:%d\n", remoteIp, remotePort);
/* Find the call or allocate a private structure if call not found */
p = find_call(call);
if (!p || !p->rtp) {
ast_log(LOG_ERROR, "Something is wrong: rtp\n");
return;
}
ast_mutex_lock(&p->lock);
ast_parse_arg(remoteIp, PARSE_ADDR, &tmp);
ast_sockaddr_set_port(&tmp, remotePort);
ast_rtp_instance_set_remote_address(p->rtp, &tmp);
if (ast_format_cmp(p->writeformat, ast_format_g726_aal2) == AST_FORMAT_CMP_EQUAL) {
ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, 2,
"audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD);
}
ast_mutex_unlock(&p->lock);
Tilghman Lesher
committed
ast_verb(0, "+++ setup_rtp_connection\n");
return;
}
void close_rtp_connection(ooCallData *call)
{
struct ooh323_pvt *p = NULL;
Tilghman Lesher
committed
ast_verb(0, "--- close_rtp_connection\n");
p = find_call(call);
if (!p) {
ast_log(LOG_ERROR, "Couldn't find matching call to close rtp "
"connection\n");
return;
}
ast_mutex_lock(&p->lock);
if (p->rtp) {
}
ast_mutex_unlock(&p->lock);
Tilghman Lesher
committed
ast_verb(0, "+++ close_rtp_connection\n");
return;
}
/*
udptl handling functions
*/
void setup_udptl_connection(ooCallData *call, const char *remoteIp,
int remotePort)
{
struct ooh323_pvt *p = NULL;
Tilghman Lesher
committed
ast_verb(0, "--- setup_udptl_connection\n");
/* Find the call or allocate a private structure if call not found */
if (!p) {
ast_log(LOG_ERROR, "Something is wrong: rtp\n");
return;
}
ast_mutex_lock(&p->lock);
if (p->owner) {
while (p->owner && ast_channel_trylock(p->owner)) {
ast_debug(1, "Failed to grab lock, trying again\n");
DEADLOCK_AVOIDANCE(&p->lock);
}
if (!p->owner) {
ast_mutex_unlock(&p->lock);
ast_log(LOG_ERROR, "Channel has no owner\n");
return;
}
} else {
ast_mutex_unlock(&p->lock);
ast_log(LOG_ERROR, "Channel has no owner\n");
return;
}
ast_parse_arg(remoteIp, PARSE_ADDR, &them);
ast_sockaddr_set_port(&them, remotePort);
ast_udptl_set_peer(p->udptl, &them);
ast_udptl_set_tag(p->udptl, "%s", ast_channel_name(p->owner));
p->t38_tx_enable = 1;
p->lastTxT38 = time(NULL);
if (p->t38support == T38_ENABLED) {
struct ast_control_t38_parameters parameters = { .request_response = 0 };
parameters.request_response = AST_T38_NEGOTIATED;
parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
parameters.rate = AST_T38_RATE_14400;
ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters));
}
if (gH323Debug) {
ast_debug(1, "Receiving UDPTL %s:%d\n", ast_sockaddr_stringify_host(&them),
ast_sockaddr_port(&them));
}
ast_channel_unlock(p->owner);
ast_mutex_unlock(&p->lock);
if(gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ setup_udptl_connection\n");
return;
}
void close_udptl_connection(ooCallData *call)
{
struct ooh323_pvt *p = NULL;
Tilghman Lesher
committed
ast_verb(0, "--- close_udptl_connection\n");
p = find_call(call);
if (!p) {
ast_log(LOG_ERROR, "Couldn't find matching call to close udptl "
"connection\n");
return;
}
ast_mutex_lock(&p->lock);
if (p->owner) {
while (p->owner && ast_channel_trylock(p->owner)) {
ast_debug(1, "Failed to grab lock, trying again\n");
DEADLOCK_AVOIDANCE(&p->lock);
}
if (!p->owner) {
ast_mutex_unlock(&p->lock);
ast_log(LOG_ERROR, "Channel has no owner\n");
return;
}
} else {
ast_mutex_unlock(&p->lock);
ast_log(LOG_ERROR, "Channel has no owner\n");
return;
}
p->t38_tx_enable = 0;
if (p->t38support == T38_ENABLED) {
struct ast_control_t38_parameters parameters = { .request_response = 0 };
parameters.request_response = AST_T38_TERMINATED;
ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters));
}
ast_channel_unlock(p->owner);
ast_mutex_unlock(&p->lock);
if(gH323Debug)
Tilghman Lesher
committed
ast_verb(0, "+++ close_udptl_connection\n");
return;
}
int update_our_aliases(ooCallData *call, struct ooh323_pvt *p)
{
int updated = -1;
ooAliases *psAlias = NULL;
if (!call->ourAliases)
return updated;
for (psAlias = call->ourAliases; psAlias; psAlias = psAlias->next) {
if (psAlias->type == T_H225AliasAddress_h323_ID) {
ast_copy_string(p->callee_h323id, psAlias->value, sizeof(p->callee_h323id));
updated = 1;
}
if (psAlias->type == T_H225AliasAddress_dialedDigits) {
ast_copy_string(p->callee_dialedDigits, psAlias->value,
sizeof(p->callee_dialedDigits));
updated = 1;
}
if (psAlias->type == T_H225AliasAddress_url_ID) {
ast_copy_string(p->callee_url, psAlias->value, sizeof(p->callee_url));
updated = 1;
}
if (psAlias->type == T_H225AliasAddress_email_ID) {
ast_copy_string(p->callee_email, psAlias->value, sizeof(p->callee_email));
updated = 1;
}
}
return updated;
}
struct ast_frame *ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p)
{
/* Retrieve audio/etc from channel. Assumes p->lock is already held. */
struct ast_frame *f;
struct ast_frame *dfr = NULL;
static struct ast_frame null_frame = { AST_FRAME_NULL, };
switch (ast_channel_fdno(ast)) {
case 0:
f = ast_rtp_instance_read(p->rtp, 0); /* RTP Audio */
p->lastrtprx = time(NULL);
break;
case 1:
f = ast_rtp_instance_read(p->rtp, 1); /* RTCP Control Channel */
break;
case 2:
f = ast_rtp_instance_read(p->vrtp, 0); /* RTP Video */
p->lastrtprx = time(NULL);
break;
case 3:
f = ast_rtp_instance_read(p->vrtp, 1); /* RTCP Control Channel for video */
break;
case 5:
f = ast_udptl_read(p->udptl); /* UDPTL t.38 data */