TT#43557 augment DTMF blocking to support directional blocking

Change-Id: I5d77b437fe746ac5f3b6c15d327755f9349b61d8
changes/66/23666/2
Richard Fuchs 7 years ago
parent 04a83027a0
commit 326c6a5818

@ -1907,24 +1907,25 @@ Disables call recording for the call. This can be sent during a call to imediatl
`block DTMF` and `unblock DTMF` Messages
----------------------------------------
These message types must include the key `call-id` in the message. They enable and disable blocking of DTMF
events (RFC 4733 type packets) for a call, respectively.
events (RFC 4733 type packets), respectively.
When DTMF blocking is enabled for a call, DTMF event packets will not be forwarded to the receiving peer.
If DTMF logging is enabled, DTMF events will still be logged to syslog while blocking is enabled. Blocking
of DTMF events happens for an entire call and can be enabled and disabled at any time during call runtime.
`block media` and `unblock media` Messages
------------------------------------------
Analogous to `block DTMF` and `unblock DTMF` but blocks media packets instead of DTMF packets. DTMF packets
can still pass through when media blocking is enabled.
Media can be blocked for an entire call if only the `call-id` key is present in the message, or can be blocked
Packets can be blocked for an entire call if only the `call-id` key is present in the message, or can be blocked
directionally for individual participants. Participants can be selected by their SIP tag if the `from-tag` key
is included in the message, or they can be selected by their SDP media address if the `address` key is included
in the message. In the latter case, the address can be an IPv4 or IPv6 address, and any participant that is
found to have a matching address advertised as their SDP media address will have their originating media
found to have a matching address advertised as their SDP media address will have their originating RTP
packets blocked (or unblocked).
Unblocking media for the entire call (i.e. only `call-id` is given) does not automatically unblock media for
participants which had their media blocked directionally, unless the string `all` is included in the `flags`
Unblocking packets for the entire call (i.e. only `call-id` is given) does not automatically unblock packets for
participants which had their packets blocked directionally, unless the string `all` is included in the `flags`
section of the message.
When DTMF blocking is enabled, DTMF event packets will not be forwarded to the receiving peer.
If DTMF logging is enabled, DTMF events will still be logged to syslog while blocking is enabled. Blocking
of DTMF events can be enabled and disabled at any time during call runtime.
`block media` and `unblock media` Messages
------------------------------------------
Analogous to `block DTMF` and `unblock DTMF` but blocks media packets instead of DTMF packets. DTMF packets
can still pass through when media blocking is enabled. Media packets can be blocked for an entire call, or
directionally for individual participants. See `block DTMF` above for details.

@ -1406,39 +1406,68 @@ found:
}
const char *call_block_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
str callid;
struct call *call;
struct call_monologue *monologue;
const char *errstr = NULL;
if (!bencode_dictionary_get_str(input, "call-id", &callid))
return "No call-id in message";
call = call_get_opmode(&callid, OP_OTHER);
if (!call)
return "Unknown call-id";
errstr = media_block_match(&call, &monologue, input);
if (errstr)
goto out;
ilog(LOG_INFO, "Blocking DTMF");
call->block_dtmf = 1;
if (monologue) {
ilog(LOG_INFO, "Blocking directional DTMF (tag '" STR_FORMAT ")",
STR_FMT(&monologue->tag));
monologue->block_dtmf = 1;
}
else {
ilog(LOG_INFO, "Blocking DTMF (entire call)");
call->block_dtmf = 1;
}
rwlock_unlock_w(&call->master_lock);
obj_put(call);
errstr = NULL;
out:
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return NULL;
return errstr;
}
const char *call_unblock_dtmf_ng(bencode_item_t *input, bencode_item_t *output) {
str callid;
struct call *call;
struct call_monologue *monologue;
const char *errstr = NULL;
struct sdp_ng_flags flags;
if (!bencode_dictionary_get_str(input, "call-id", &callid))
return "No call-id in message";
call = call_get_opmode(&callid, OP_OTHER);
if (!call)
return "Unknown call-id";
errstr = media_block_match(&call, &monologue, input);
if (errstr)
goto out;
ilog(LOG_INFO, "Unblocking DTMF");
call->block_dtmf = 0;
call_ng_process_flags(&flags, input);
rwlock_unlock_w(&call->master_lock);
obj_put(call);
if (monologue) {
ilog(LOG_INFO, "Unblocking directional DTMF (tag '" STR_FORMAT ")",
STR_FMT(&monologue->tag));
monologue->block_dtmf = 0;
}
else {
ilog(LOG_INFO, "Unblocking DTMF (entire call)");
call->block_dtmf = 0;
if (flags.all) {
for (GList *l = call->monologues.head; l; l = l->next) {
monologue = l->data;
monologue->block_dtmf = 0;
}
}
}
errstr = NULL;
out:
if (call) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
}
return NULL;
}
@ -1511,8 +1540,6 @@ out:
obj_put(call);
}
return NULL;
}

@ -650,14 +650,14 @@ static int packet_dtmf(struct codec_ssrc_handler *ch, struct transcode_packet *p
}
}
if (!mp->call->block_dtmf)
if (!mp->call->block_dtmf && !mp->media->monologue->block_dtmf)
packet_dtmf_fwd(ch, packet, mp, 1);
return 0;
}
static void packet_dtmf_dup(struct codec_ssrc_handler *ch, struct transcode_packet *packet,
struct media_packet *mp)
{
if (!mp->call->block_dtmf)
if (!mp->call->block_dtmf && !mp->media->monologue->block_dtmf)
packet_dtmf_fwd(ch, packet, mp, 0);
}

@ -1220,6 +1220,8 @@ static int redis_tags(struct call *c, struct redis_list *tags) {
if (!redis_hash_get_str(&s, rh, "label"))
call_str_cpy(c, &ml->label, &s);
redis_hash_get_time_t(&ml->deleted, rh, "deleted");
if (!redis_hash_get_int(&ii, rh, "block_dtmf"))
ml->block_dtmf = ii ? 1 : 0;
if (!redis_hash_get_int(&ii, rh, "block_media"))
ml->block_media = ii ? 1 : 0;
@ -1965,6 +1967,7 @@ char* redis_encode_json(struct call *c) {
JSON_SET_SIMPLE("created","%llu",(long long unsigned) ml->created);
JSON_SET_SIMPLE("active","%u",ml->active_dialogue ? ml->active_dialogue->unique_id : -1);
JSON_SET_SIMPLE("deleted","%llu",(long long unsigned) ml->deleted);
JSON_SET_SIMPLE("block_dtmf","%i",ml->block_dtmf ? 1 : 0);
JSON_SET_SIMPLE("block_media","%i",ml->block_media ? 1 : 0);
if (ml->tag.s)

@ -365,6 +365,7 @@ struct call_monologue {
struct call_monologue *active_dialogue;
GQueue medias;
int block_dtmf:1;
int block_media:1;
};

Loading…
Cancel
Save