summaryrefslogtreecommitdiff
path: root/channels/chan_h323.c
diff options
context:
space:
mode:
authorPaul Cadach <paul@odt.east.telecom.kz>2006-09-28 10:41:38 +0000
committerPaul Cadach <paul@odt.east.telecom.kz>2006-09-28 10:41:38 +0000
commit9cf1f14ed59be92cf9bb12003441306345885600 (patch)
tree549d5d4dee7804215437b180a6be243074532c9b /channels/chan_h323.c
parentb6a81ea3ec0ddca72a84fb70f29aceb50bd0b8df (diff)
Handle HOLD/RETRIEVE notifications
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@43845 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_h323.c')
-rw-r--r--channels/chan_h323.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index 0fad86ffa..836093f44 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -117,6 +117,7 @@ rfc2833_cb on_set_rfc2833_payload;
hangup_cb on_hangup;
setcapabilities_cb on_setcapabilities;
setpeercapabilities_cb on_setpeercapabilities;
+onhold_cb on_hold;
/* global debug flag */
int h323debug;
@@ -866,7 +867,7 @@ static int oh323_indicate(struct ast_channel *c, int condition, const void *data
ast_mutex_unlock(&pvt->lock);
if (h323debug)
- ast_log(LOG_DEBUG, "OH323: Indicating %d on %s\n", condition, token);
+ ast_log(LOG_DEBUG, "OH323: Indicating %d on %s (%s)\n", condition, token, c->name);
switch(condition) {
case AST_CONTROL_RINGING:
@@ -910,11 +911,14 @@ static int oh323_indicate(struct ast_channel *c, int condition, const void *data
free(token);
return -1;
case AST_CONTROL_HOLD:
+ h323_hold_call(token, 1);
+ /* We should start MOH only if remote party isn't provide audio for us */
ast_moh_start(c, data, NULL);
if (token)
free(token);
return 0;
case AST_CONTROL_UNHOLD:
+ h323_hold_call(token, 0);
ast_moh_stop(c);
if (token)
free(token);
@@ -1338,6 +1342,17 @@ static int update_common_options(struct ast_variable *v, struct call_options *op
options->tunnelOptions |= H323_TUNNEL_QSIG;
else
ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
+ } else if (!strcasecmp(v->name, "hold")) {
+ if (!strcasecmp(v->value, "none"))
+ options->holdHandling = ~0;
+ else if (!strcasecmp(v->value, "notify"))
+ options->holdHandling |= H323_HOLD_NOTIFY;
+ else if (!strcasecmp(v->value, "q931only"))
+ options->holdHandling |= H323_HOLD_NOTIFY | H323_HOLD_Q931ONLY;
+ else if (!strcasecmp(v->value, "h450"))
+ options->holdHandling |= H323_HOLD_H450;
+ else
+ ast_log(LOG_WARNING, "Invalid value %s for %s at line %d\n", v->value, v->name, v->lineno);
} else
return 1;
@@ -1364,6 +1379,7 @@ static struct oh323_user *build_user(char *name, struct ast_variable *v, struct
user->ha = (struct ast_ha *)NULL;
memcpy(&user->options, &global_options, sizeof(user->options));
user->options.dtmfmode = 0;
+ user->options.holdHandling = 0;
/* Set default context */
strncpy(user->context, default_context, sizeof(user->context) - 1);
if (user && !found)
@@ -1410,6 +1426,10 @@ static struct oh323_user *build_user(char *name, struct ast_variable *v, struct
}
if (!user->options.dtmfmode)
user->options.dtmfmode = global_options.dtmfmode;
+ if (user->options.holdHandling == ~0)
+ user->options.holdHandling = 0;
+ else if (!user->options.holdHandling)
+ user->options.holdHandling = global_options.holdHandling;
ASTOBJ_UNMARK(user);
ast_free_ha(oldha);
return user;
@@ -1472,6 +1492,7 @@ static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, s
peer->ha = NULL;
memcpy(&peer->options, &global_options, sizeof(peer->options));
peer->options.dtmfmode = 0;
+ peer->options.holdHandling = 0;
peer->addr.sin_port = htons(h323_signalling_port);
peer->addr.sin_family = AF_INET;
if (!found && name)
@@ -1511,6 +1532,10 @@ static struct oh323_peer *build_peer(const char *name, struct ast_variable *v, s
}
if (!peer->options.dtmfmode)
peer->options.dtmfmode = global_options.dtmfmode;
+ if (peer->options.holdHandling == ~0)
+ peer->options.holdHandling = 0;
+ else if (!peer->options.holdHandling)
+ peer->options.holdHandling = global_options.holdHandling;
ASTOBJ_UNMARK(peer);
ast_free_ha(oldha);
return peer;
@@ -2450,6 +2475,32 @@ static void set_local_capabilities(unsigned call_reference, const char *token)
ast_log(LOG_DEBUG, "Capabilities for connection %s is set\n", token);
}
+static void remote_hold(unsigned call_reference, const char *token, int is_hold)
+{
+ struct oh323_pvt *pvt;
+
+ if (h323debug)
+ ast_log(LOG_DEBUG, "Setting %shold status for connection %s\n", (is_hold ? "" : "un"), token);
+
+ pvt = find_call_locked(call_reference, token);
+ if (!pvt)
+ return;
+ if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
+ if (is_hold)
+ ast_queue_control(pvt->owner, AST_CONTROL_HOLD);
+ else
+ ast_queue_control(pvt->owner, AST_CONTROL_UNHOLD);
+ ast_channel_unlock(pvt->owner);
+ }
+ else {
+ if (is_hold)
+ pvt->newcontrol = AST_CONTROL_HOLD;
+ else
+ pvt->newcontrol = AST_CONTROL_UNHOLD;
+ }
+ ast_mutex_unlock(&pvt->lock);
+}
+
static void *do_monitor(void *data)
{
int res;
@@ -2767,6 +2818,7 @@ static int reload_config(int is_reload)
global_options.dtmfcodec[0] = H323_DTMF_RFC2833_PT;
global_options.dtmfcodec[1] = H323_DTMF_CISCO_PT;
global_options.dtmfmode = 0;
+ global_options.holdHandling = 0;
global_options.capability = GLOBAL_CAPABILITY;
global_options.bridge = 1; /* Do native bridging by default */
strncpy(default_context, "default", sizeof(default_context) - 1);
@@ -2861,6 +2913,10 @@ static int reload_config(int is_reload)
}
if (!global_options.dtmfmode)
global_options.dtmfmode = H323_DTMF_RFC2833;
+ if (global_options.holdHandling == ~0)
+ global_options.holdHandling = 0;
+ else if (!global_options.holdHandling)
+ global_options.holdHandling = H323_HOLD_H450;
for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
if (strcasecmp(cat, "general")) {
@@ -3175,7 +3231,8 @@ static enum ast_module_load_result load_module(void)
set_dtmf_payload,
hangup_connection,
set_local_capabilities,
- set_peer_capabilities);
+ set_peer_capabilities,
+ remote_hold);
/* start the h.323 listener */
if (h323_start_listener(h323_signalling_port, bindaddr)) {
ast_log(LOG_ERROR, "Unable to create H323 listener.\n");