webconference: participant ID / findParticipant

sayer/1.4-spce2.6
Stefan Sayer 16 years ago
parent 9d7ccee705
commit b2b11301ff

@ -29,6 +29,7 @@ AmArg ConferenceRoomParticipant::asArgArray() {
res.push(AmArg((int)status));
res.push(AmArg(last_reason.c_str()));
res.push(AmArg((int)muted));
res.push(AmArg(participant_id));
return res;
}
@ -45,7 +46,9 @@ void ConferenceRoomParticipant::updateStatus(ConferenceRoomParticipant::Particip
updateAccess(now);
}
ConferenceRoom::ConferenceRoom() {
ConferenceRoom::ConferenceRoom()
: expiry_time(0)
{
gettimeofday(&last_access_time, NULL);
}
@ -91,12 +94,14 @@ vector<string> ConferenceRoom::participantLtags() {
}
void ConferenceRoom::newParticipant(const string& localtag,
const string& number) {
const string& number,
const string& participant_id) {
gettimeofday(&last_access_time, NULL);
participants.push_back(ConferenceRoomParticipant());
participants.back().localtag = localtag;
participants.back().number = number;
participants.back().participant_id = participant_id;
}
bool ConferenceRoom::hasParticipant(const string& localtag) {

@ -31,6 +31,7 @@ struct ConferenceRoomParticipant {
string number;
ParticipantStatus status;
string last_reason;
string participant_id;
int muted;
@ -70,7 +71,8 @@ struct ConferenceRoom {
vector<string> participantLtags();
void newParticipant(const string& localtag, const string& number);
void newParticipant(const string& localtag, const string& number,
const string& participant_id);
bool updateStatus(const string& part_tag,
ConferenceRoomParticipant::ParticipantStatus newstatus,

@ -72,6 +72,9 @@ bool WebConferenceFactory::ignore_pin = false;
bool WebConferenceFactory::PrivateRoomsMode = false;
string WebConferenceFactory::participant_id_paramname; // default: param not used
string WebConferenceFactory::participant_id_hdr = "X-ParticipantID"; // default header
int WebConferenceFactory::onLoad()
{
return getInstance()->load();
@ -90,6 +93,11 @@ int WebConferenceFactory::load()
// get application specific global parameters
configureModule(cfg);
participant_id_paramname = cfg.getParameter("participant_id_param");
if (cfg.hasParameter("participant_id_header"))
participant_id_hdr = cfg.getParameter("participant_id_header");
// get prompts
AM_PROMPT_START;
AM_PROMPT_ADD(FIRST_PARTICIPANT, WEBCONF_ANNOUNCE_PATH "first_paricipant.wav");
@ -243,14 +251,15 @@ bool WebConferenceFactory::isValidConference(const string& conf_id) {
bool WebConferenceFactory::newParticipant(const string& conf_id,
const string& localtag,
const string& number) {
const string& number,
const string& participant_id) {
rooms_mut.lock();
if (PrivateRoomsMode && rooms.find(conf_id) == rooms.end()) {
rooms_mut.unlock();
return false;
}
rooms[conf_id].newParticipant(localtag, number);
rooms[conf_id].newParticipant(localtag, number, participant_id);
rooms_mut.unlock();
return true;
}
@ -471,6 +480,10 @@ void WebConferenceFactory::invoke(const string& method,
args.assertArrayFmt("s");
listRooms(args, ret);
ret.push(getServerInfoString().c_str());
} else if(method == "findParticipant"){
args.assertArrayFmt("s");
findParticipant(args, ret);
ret.push(getServerInfoString().c_str());
} else if(method == "_list"){
ret.push("roomCreate");
ret.push("roomDelete");
@ -486,6 +499,7 @@ void WebConferenceFactory::invoke(const string& method,
ret.push("vqRoomFeedback");
ret.push("getRoomPassword");
ret.push("listRooms");
ret.push("findParticipant");
} else
throw AmDynInvoke::NotImplemented(method);
}
@ -653,6 +667,7 @@ void WebConferenceFactory::dialout(const AmArg& args, AmArg& ret) {
string auth_pwd = args.get(6).asCStr();
string callee_domain = domain;
string headers;
string participant_id;
if (args.size()>7) {
try {
@ -679,6 +694,16 @@ void WebConferenceFactory::dialout(const AmArg& args, AmArg& ret) {
callee_domain = domain;
}
}
if (args.size()>9) {
try {
assertArgCStr(args.get(9));
participant_id = args.get(9).asCStr();
}
catch (AmArg::TypeMismatchException &e) {
participant_id = "";
}
}
}
string from = "sip:" + from_user + "@" + domain;
@ -694,10 +719,10 @@ void WebConferenceFactory::dialout(const AmArg& args, AmArg& ret) {
rooms_mut.unlock();
if (!is_valid_room) {
ret.push(1);
ret.push("wrong adminpin or inexisting room");
ret.push("");
return;
ret.push(1);
ret.push("wrong adminpin or inexisting room");
ret.push("");
return;
}
DBG("dialout webconference room '%s', from '%s', to '%s'",
@ -716,7 +741,7 @@ void WebConferenceFactory::dialout(const AmArg& args, AmArg& ret) {
ret.push(0);
ret.push("OK");
ret.push(localtag.c_str());
newParticipant(room, localtag, to);
newParticipant(room, localtag, to, participant_id);
updateStatus(room, localtag,
ConferenceRoomParticipant::Connecting,
"INVITE");
@ -869,6 +894,25 @@ void WebConferenceFactory::listRooms(const AmArg& args, AmArg& ret) {
ret.push(room_list);
}
void WebConferenceFactory::findParticipant(const AmArg& args, AmArg& ret) {
string participant_id = args.get(0).asCStr();
AmArg r_ret;
r_ret.assertArray();
rooms_mut.lock();
for (map<string, ConferenceRoom>::iterator it =
rooms.begin(); it != rooms.end(); it++) {
for (list<ConferenceRoomParticipant>::iterator p_it=
it->second.participants.begin(); p_it != it->second.participants.end(); p_it++) {
if (p_it->participant_id == participant_id) {
r_ret.push(it->first);
break;
}
}
}
rooms_mut.unlock();
ret.push(r_ret);
}
void WebConferenceFactory::vqRoomFeedback(const AmArg& args, AmArg& ret) {
string room = args.get(0).asCStr();
string adminpin = args.get(1).asCStr();

@ -137,6 +137,13 @@ public:
static bool PrivateRoomsMode;
// P-App-Param parameter to get participant ID from
static string participant_id_paramname;
// if participant_id_paramname not configured:
// header to get participant ID from
static string participant_id_hdr;
WebConferenceFactory(const string& _app_name);
AmSession* onInvite(const AmSipRequest&);
AmSession* onInvite(const AmSipRequest& req,
@ -146,7 +153,8 @@ public:
bool isValidConference(const string& conf_id);
bool newParticipant(const string& conf_id,
const string& localtag,
const string& number);
const string& number,
const string& participant_id);
void updateStatus(const string& conf_id,
const string& localtag,
ConferenceRoomParticipant::ParticipantStatus status,
@ -186,6 +194,8 @@ public:
void getRoomPassword(const AmArg& args, AmArg& ret);
void listRooms(const AmArg& args, AmArg& ret);
void findParticipant(const AmArg& args, AmArg& ret);
};

@ -112,6 +112,22 @@ void WebConferenceDialog::connectConference(const string& room) {
void WebConferenceDialog::onSessionStart(const AmSipRequest& req) {
time(&connect_ts);
if (WebConferenceFactory::participant_id_paramname.length()) {
string appparams = getHeader(req.hdrs, PARAM_HDR);
if (appparams.length()) {
participant_id = get_header_param(appparams,
WebConferenceFactory::participant_id_paramname);
}
} else if (WebConferenceFactory::participant_id_hdr.length()) {
participant_id = getHeader(req.hdrs, WebConferenceFactory::participant_id_hdr);
}
if (participant_id.empty()) {
DBG("no Participant ID set\n");
} else {
DBG("Participant ID set to '%s'\n", participant_id.c_str());
}
// direct room access?
if (conf_id.empty()) {
state = EnteringPin;
@ -122,7 +138,8 @@ void WebConferenceDialog::onSessionStart(const AmSipRequest& req) {
DBG("########## direct connect conference #########\n");
if (!factory->newParticipant(conf_id,
getLocalTag(),
dlg.remote_party)) {
dlg.remote_party,
participant_id)) {
DBG("inexisting conference room\n");
state = PlayErrorFinish;
setInOut(&play_list,&play_list);
@ -276,7 +293,8 @@ void WebConferenceDialog::process(AmEvent* ev)
if (!factory->newParticipant(pin_str,
getLocalTag(),
dlg.remote_party)) {
dlg.remote_party,
participant_id)) {
DBG("inexisting conference room\n");
state = PlayErrorFinish;
setInOut(&play_list,&play_list);

@ -83,6 +83,9 @@ private:
time_t connect_ts;
time_t disconnect_ts;
// ID from X-ParticipantID header
string participant_id;
public:
WebConferenceDialog(AmPromptCollection& prompts,
WebConferenceFactory* my_f,

@ -131,6 +131,16 @@ stats_dir=/var/log/sems-webconference/
#
# predefined_rooms=discussion:some_pwd;support:other_pwd;
# Participant ID (default: X-ParticipantID header)
#
# get participant ID from P-App-Param:
#participant_id_param=participantid
#
# or, get participant ID from header:
#participant_id_header=x-participantid
###############################################################
# RFC4028 Session Timer
#

@ -57,6 +57,19 @@ If a room exists and the adminpin is not set (for example if the room is created
by dial-in), the first call to roomInfo/dialout/kick/... with room/adminpin will
set the adminpin.
Participant ID
--------------
In some service environments, it may be necessary to determine in which conference
rooms a certain user is at the moment. For example, if the active conferences of a
user should be displayed on a web page, the conference bridge may be queried for the
room a user is in.
The findParticipant(string participant_id) function returns a list of rooms where the
participant with a given ID is in. This participant ID can be given with
- a parameter to the dialout() function
- a header or P-App-Param parameter on incoming calls (see participant_id_param and
participant_id_header configuration in webconference.conf)
implemented DI functions
------------------------
@ -94,7 +107,7 @@ roomInfo(string room, string adminpin):
----
dialout(string room, string adminpin, string callee,
string from_user, string domain,
string auth_user, string auth_pwd [, headers [, callee_domain]]) :
string auth_user, string auth_pwd [, headers [, callee_domain, [participant_id]]]) :
int code, string result, string callid
code/result:
@ -142,6 +155,10 @@ getRoomPassword(string master_pwd, string room)
listRooms(string master_pwd)
int code, string result
----
findParticipant(string participant_id)
rooms: array of string
find all rooms a participant is in
-----
additionally there is feedback functions to save call quality reports
from users: vqRoomFeedback, vqCallFeedback, vqConferenceFeedback.

Loading…
Cancel
Save