Properly propagating call id for call response handling.

Previously a new call id was generated for INVITE and CANCEL.
Now the id generated during the initial INVITE will be used for
corresponding CANCEL events. Also, adding the ability to
trigger a call cancel via the poltergeist update api.
This commit is contained in:
Jacob MacElroy 2018-05-24 15:20:52 +00:00
parent 6a1e9e256d
commit e367490839
2 changed files with 103 additions and 39 deletions

View File

@ -67,17 +67,29 @@ module:hook("muc-broadcast-presence", function (event)
return
end
local invite = function()
local url = assert(url_from_room_jid(event.stanza.attr.from))
ext_events.invite(event.stanza, url)
local call_id = event.stanza:get_child_text("call_id")
if not call_id then
module:log("info", "A call id was not provided in the status.")
return
end
local cancel = function()
local invite = function()
local url = assert(url_from_room_jid(event.stanza.attr.from))
ext_events.invite(event.stanza, url, call_id)
end
local cancel = function()
local url = assert(url_from_room_jid(event.stanza.attr.from))
local status = event.stanza:get_child_text("status")
ext_events.cancel(event.stanza, url, string.lower(status))
ext_events.cancel(event.stanza, url, string.lower(status), call_id)
end
local should_cancel = event.stanza:get_child_text("call_cancel")
if should_cancel == "true" then
cancel()
return
end
local switch = function(status)
case = {
[calling_status] = function() invite() end,

View File

@ -108,6 +108,27 @@ function remove_username(room, nick)
end
end
-- Provides a new presence stanza for a poltergeist.
-- @param room the room instance
-- @param nick the user nick
function generate_poltergeist_presence(room, nick, status)
local presence_stanza = st.presence({
to = room.jid.."/"..nick,
from = poltergeist_component.."/"..nick,
}):tag("x", { xmlns = MUC_NS }):up();
presence_stanza:tag("call_cancel"):text(nil):up();
presence_stanza:tag("call_id"):text(nil):up();
if status then
presence_stanza:tag("status"):text(status):up();
else
presence_stanza:tag("status"):text(nil):up();
end
return presence_stanza;
end
--- Verifies room name, domain name with the values in the token
-- @param token the token we received
-- @param room_name the room name
@ -182,7 +203,7 @@ prosody.events.add_handler("pre-jitsi-authentication", function(session)
if (have_poltergeist_occupant(room, nick)) then
-- notify that user connected using the poltergeist
update_poltergeist_occupant_status(
room, nick, "connected");
room, nick, "connected");
remove_poltergeist_occupant(room, nick, true);
end
@ -202,10 +223,7 @@ end);
function create_poltergeist_occupant(room, nick, name, avatar, status, context)
log("debug", "create_poltergeist_occupant %s", nick);
-- Join poltergeist occupant to room, with the invited JID as their nick
local join_presence = st.presence({
to = room.jid.."/"..nick,
from = poltergeist_component.."/"..nick
}):tag("x", { xmlns = MUC_NS }):up();
local join_presence = generate_poltergeist_presence(room, nick, status)
if (name) then
join_presence:tag(
@ -215,9 +233,6 @@ function create_poltergeist_occupant(room, nick, name, avatar, status, context)
if (avatar) then
join_presence:tag("avatar-url"):text(avatar):up();
end
if (status) then
join_presence:tag("status"):text(status):up();
end
-- If the room has a password set, let the poltergeist enter using it
local room_password = room:get_password();
@ -226,6 +241,9 @@ function create_poltergeist_occupant(room, nick, name, avatar, status, context)
join:tag("password", { xmlns = MUC_NS }):text(room_password);
end
local call_id = get_username(room, context.user.id);
join_presence:tag("call_id"):text(get_username(room, context.user.id)):up();
update_presence_identity(
join_presence,
context.user,
@ -278,15 +296,13 @@ end
-- @param room the room instance where to remove the occupant
-- @param nick the nick of the occupant to remove
-- @param status the status to update
function update_poltergeist_occupant_status(room, nick, status)
-- @param call_details is a table of call flow details
function update_poltergeist_occupant_status(room, nick, status, call_details)
local update_presence = get_presence(room, nick);
if (not update_presence) then
-- no presence found for occupant, create one
update_presence = st.presence({
to = room.jid.."/"..nick,
from = poltergeist_component.."/"..nick
});
update_presence = generate_poltergeist_presence(room, nick)
else
-- update occupant presence with appropriate to and from
-- so we can send it again
@ -295,31 +311,56 @@ function update_poltergeist_occupant_status(room, nick, status)
update_presence.attr.from = poltergeist_component.."/"..nick;
end
local once = false;
-- the status tag we will attach
local statusTag = st.stanza("status"):text(status);
-- if there is already a status tag replace it
update_presence:maptags(function (tag)
if tag.name == statusTag.name then
if not once then
once = true;
return statusTag;
else
return nil;
end
end
return tag;
end);
if (not once) then
-- no status tag was repleced, attach it
update_presence:add_child(statusTag);
end
update_presence = update_presence_tags(update_presence, status, call_details)
room:handle_normal_presence(
prosody.hosts[poltergeist_component], update_presence);
end
-- Updates the status tags and call flow tags of an existing poltergeist's
-- presence.
-- @param presence_stanza is the actual presence stanza for a poltergeist.
-- @param status is the new status to be updated in the stanza.
-- @param call_details is a table of call flow signal information.
function update_presence_tags(presence_stanza, status, call_details)
local call_cancel = false;
local call_id = nil;
-- Extract optional call flow signal information.
if call_details then
call_id = call_details["id"];
if call_details["cancel"] then
call_cancel = call_details["cancel"];
end
end
presence_stanza:maptags(function (tag)
if tag.name == "status" then
if call_cancel then
-- If call cancel is set then the status should not be changed.
return tag
end
return st.stanza("status"):text(status);
elseif tag.name == "call_id" then
if call_id then
return st.stanza("call_id"):text(call_id);
else
-- If no call id is provided the re-use the existing id.
return tag;
end
elseif tag.name == "call_cancel" then
if call_cancel then
return st.stanza("call_cancel"):text("true");
else
return st.stanza("call_cancel"):text("false");
end
end
end);
return presence_stanza
end
-- Checks for existance of a poltergeist occupant
-- @param room the room instance where to check for occupant
-- @param nick the nick of the occupant
@ -436,6 +477,12 @@ function handle_update_poltergeist (event)
local room_name = params["room"];
local group = params["group"];
local status = params["status"];
local call_id = params["callid"];
local call_cancel = false
if params["callcancel"] == "true" then
call_cancel = true;
end
if not verify_token(params["token"], room_name, group, {}) then
return 403;
@ -452,9 +499,14 @@ function handle_update_poltergeist (event)
return 404;
end
local call_details = {
["cancel"] = call_cancel;
["id"] = call_id;
};
local nick = string.sub(username, 0, 8);
if (have_poltergeist_occupant(room, nick)) then
update_poltergeist_occupant_status(room, nick, status);
update_poltergeist_occupant_status(room, nick, status, call_details);
return 200;
else
return 404;