Еще один sppr - голосовые комнаты. На этот раз они настоящие.

От: Sergey Kronshtadtov <CGatePro_at_mx_ru>
Дата: Thu 14 Jan 2010 - 21:39:01 MSK


Найденные ошибки приветствуются.

Суть сервиса:
Люди звонят по номеру голосовой комнаты, представляются и попадают в конференцию, где разговаривают между собой. Если человек один - играет музыка.
Все участники абсолютно равноправны.

Из минусов - нет приватности.
Из плюсов - все предельно просто.

Управление:
# - отключиться от комнаты

*5 - огласить всем список участников
*6 - выключить микрофон
*7 - включить микрофон
*8 - выключить или включить музыку, если участник один
*0 - завершение "главного" комнатного процесса и отключение всех участников.

Комнаты можно вызывать из роутера записями вида: n:s:<2801@*> = svkvoiceroom{000001}#pbx@tn.arm.ru n:s:<2802@*> = svkvoiceroom{000002}#pbx@tn.arm.ru

В коде присутствуют адреса - ownerAddress и hostAddress. ЗАМЕНИТЕ ИХ НА СВОИ.
ownerAddress - адрес "хозяина" комнат. Может потребоваться, например, для удаления митинга вручную.
hostAddress - адрес, с которого рассылаются уведомления в виде instant messages.

Файл svkvoiceroom.sppr:


//
// Voice Room v.1.05
//
// You can contact me at svk@arm.ru
//

entry hostEntry forward;
procedure playSine (freq, msec) external; procedure playMenu (promptFile, optionValue) external;

entry main is

sysLog ("Voice room main task started");

roomNumber = vars().startParameter[0];

if acceptCall () != null then

    sysLog ("Failed to accept the call");     stop;
end if;

clearDTMF ();
playFile ("conferenceentry");

meetingInfo = findMeeting (null, roomNumber);

if meetingInfo == null or else meetingInfo.id == null then

    hostTask = spawn hostEntry (roomNumber);     if hostTask == null then

        sysLog ("Failed to create the host task");
        clearDTMF ();
        playFile ("failure");
        stop;

    end if;
    index = 0;
    while index <= 10 and then (meetingInfo == null or else meetingInfo.id == null)

    loop

        sysLog ("Waiting for the host task");
        meetingInfo = findMeeting (null, roomNumber);
        clearDTMF ();
        input = readInput (1);
        if isDisconnectEvent (input) then
            sysLog ("Voice room main task stopped because of the 
disconnect event");
            stop;
        end if;
        index = index + 1;

    end loop;
    if meetingInfo == null or else meetingInfo.id == null then
        sysLog ("Host task is not operational");
        clearDTMF ();
        playFile ("failure");
        stop;

    end if;
end if;

clearDTMF ();

void (sendEvent (meetingInfo.id, "getPartyIntros", null));

input = readInput (5);

if isDictionary (input) and then input.what == "partyIntros" and then input.sender == meetingInfo.id then

    if (length (input.parameter) > 0) then

        sysLog ("Playing party intros");
        clearDTMF ();
        playFile ("conferencemembers");
        index = 0;
        while index < length (input.parameter)
        loop
            playSine (2000, 50);
            play (input.parameter.(input.parameter[index]));
            index = index + 1;
        end loop;
        playSine (2000, 500);
    else
        sysLog ("No party intros to play");
    end if;
else

    sysLog ("Unexpected main task event in place of party intros parameter from the host task");

    if not isDisconnectEvent (input) then

        clearDTMF ();
        playFile ("failure");

    end if;
    stop;
end if;

partyIntro = null;

if remoteAuthentication () != null then

    partyIntro = readSiteFile ("~" + remoteAuthentication () + "/myname.wav");
end if;

if partyIntro == null then

    clearDTMF ();
    playFile ("introduceyourself");
    playFile ("finishbypound");
    clearDTMF ();
    playFile ("recordingbeep");
// clearDTMF ();

    partyIntro = record (5);
end if;

if partyIntro == null then

    sysLog ("Getting default party intro");     partyIntro = readFile ("dialtone.wav"); end if;

// clearDTMF ();

// playMenu ("tomuteyourline", "*6");
// playMenu ("tounmute", "*7");
// playMenu ("todisconnect", "#");

clearDTMF ();

playFile ("joiningconference");

input = readInput (0);

while input != null
loop

    if isDisconnectEvent (input) then

        sysLog ("Voice room main task stopped because of the disconnect event");

        stop;
    end if;
    input = readInput (1);
end loop;

void (sendEvent (meetingInfo.id, "partyIntro", partyIntro)); void (sendEvent (meetingInfo.id, "partyAddress", SIPURIToEmail (RemoteURI ())));

sysLog ("Joining the conference");

if startBridge (meetingInfo.id) != null then

    sysLog ("Failed to start bridge to the host task");     void (sendEvent (meetingInfo.id, "partyIntro", null));     void (sendEvent (meetingInfo.id, "partyAddress", null));     clearDTMF ();
    playFile ("failure");
    stop;
end if;

playMusic = false;

clearDTMF ();

loop

input = readInput (60);

exitIf input != null and then (input == "#" or else not isString (input));

if input == "*" then

    input = readInput (5);
    if input == null then

        input = "*";
    elif isDigit (input) then

        input = "*" + input;
    end if;
end if;

if input == "*5" then

    void (sendEvent (meetingInfo.id, "playPartyIntros", null));

elif input == "*6" then

    void (sendEvent (meetingInfo.id, "mute", true));

elif input == "*7" then

    void (sendEvent (meetingInfo.id, "mute", false));

elif input == "*8" then

    void (sendEvent (meetingInfo.id, "playMusic", playMusic));     playMusic = not playMusic;

elif input == "*0" then

    void (sendEvent (meetingInfo.id, "exitNow", null));

elif input != null and then isString (input) then

    void (sendEvent (meetingInfo.id, "unknownEvent", null));

end if;

end loop;

if not isBreakBridgeEvent (input) then

    void (breakBridge ());
end if;

if isDisconnectEvent (input) then

    sysLog ("Voice room main task loop stopped because of the disconnect event");
else

    clearDTMF ();
    playFile ("disconnectedconference");     playFile ("goodbye");
end if;

sysLog ("Voice room main task stopped normally");

end entry;

entry hostEntry is

//
// !!! Change those addresses !!!
//

ownerAddress = "svk@arm.ru";
hostAddress = "pbx@tn.arm.ru";

sysLog ("Voice room host task started");

roomNumber = vars().startParameter;

meetingInfo = findMeeting (null, roomNumber);

if meetingInfo == null then

    sysLog ("Creating meeting");
    parameter = newDictionary ();
    parameter.isOpen = true;
    parameter.owner = ownerAddress;
    if createMeeting (null, roomNumber, parameter) != null then

        sysLog ("Failed to create the meeting");
        stop;

    end if;
end if;

if activateMeeting (null, roomNumber) != null then

    sysLog ("Failed to activate the meeting");     stop;
end if;

playMusic = false;
exitNow = false;

partyIntros = newDictionary ();
partyAddresses = newDictionary ();

loop

exitIf exitNow;

if playMusic and then length (partyAddresses) == 1 then

    playFileInLoop ("holdmusic", 60000);     input = readInput (0);
else

    input = readInput (60);
end if;

if input == null then

    if length (partyAddresses) == 0 then

        exitNow = true;
    end if;

elif isStartBridgeEvent (input) then

    if attachMixer (input) == null then

        sysLog (partyAddresses.(string (input.sender)) + " has joined the voice room " + roomNumber);

        instantMessageContent = partyAddresses.(string (input.sender)) + " has joined the voice room " + roomNumber + " at " + objectToString (localTime ());

        index = 0;
        while index < length (partyAddresses)
        loop
            if partyAddresses.(partyAddresses[index]) == 
partyAddresses.(string (input.sender)) then
                void (sendInstantMessage (hostAddress, 
partyAddresses.(partyAddresses[index]), "You are joined the voice room " + roomNumber + " at " + objectToString (localTime ())));
            else
                void (sendInstantMessage (hostAddress, 
partyAddresses.(partyAddresses[index]), instantMessageContent));
            end if;
            index = index + 1;
        end loop;
        if length (partyAddresses) >= 2 then
            play (partyIntros.(string (input.sender)));
            playFile ("joinedconference");
        end if;
    else   
        partyIntros.(string (input.sender)) = null;
        partyAddresses.(string (input.sender)) = null;
    end if;
    if length (partyAddresses) == 1 then

        playMusic = true;
    else

        playMusic = false;
    end if;

elif isBreakBridgeEvent (input) then

    sysLog (partyAddresses.(string (input.sender)) + " has left from the voice room " + roomNumber);

    instantMessageContent = partyAddresses.(string (input.sender)) + " has left from the voice room " + roomNumber + " at " + objectToString (localTime ());

    index = 0;
    while index < length (partyAddresses)     loop

        if partyAddresses.(partyAddresses[index]) == partyAddresses.(string (input.sender)) then

            void (sendInstantMessage (hostAddress, partyAddresses.(partyAddresses[index]), "You are left from the voice room " + roomNumber + " at " + objectToString (localTime ())));

        else
            void (sendInstantMessage (hostAddress, 
partyAddresses.(partyAddresses[index]), instantMessageContent));
        end if;
        index = index + 1;

    end loop;
    if length (partyAddresses) >= 2 then
        play (partyIntros.(string (input.sender)));
        playFile ("leftconference");

    end if;
    partyIntros.(string (input.sender)) = null;     partyAddresses.(string (input.sender)) = null;     if length (partyAddresses) == 1 then

        playMusic = true;
    else

        playMusic = false;
    end if;

elif isDictionary (input) and then input.what == "partyIntro" then

    partyIntros.(string (input.sender)) = input.parameter;

elif isDictionary (input) and then input.what == "partyAddress" then

    partyAddresses.(string (input.sender)) = input.parameter;

elif isDictionary (input) and then input.what == "getPartyIntros" then

    void (sendEvent (input.sender, "partyIntros", partyIntros));

elif isDictionary (input) and then input.what == "getPartyAddresses" then

    void (sendEvent (input.sender, "partyAddresses", partyAddresses));

elif isDictionary (input) and then input.what == "playPartyIntros" then

    partyAddressesList = "";
    index = 0;
    while index < length (partyAddresses)     loop

        partyAddressesList = partyAddressesList + " " + partyAddresses.(partyAddresses[index]);

        index = index + 1;
    end loop;
    instantMessageContent = "Conference members for the voice room " + roomNumber + " at " + objectToString (localTime ()) + " are:" + partyAddressesList;

    index = 0;
    while index < length (partyAddresses)     loop

        void (sendInstantMessage (hostAddress, partyAddresses.(partyAddresses[index]), instantMessageContent));

        index = index + 1;
    end loop;
    playFile ("conferencemembers");
    index = 0;
    while index < length (partyIntros)
    loop

        playSine (2000, 50);
        play (partyIntros.(partyIntros[index]));
        index = index + 1;

    end loop;
    playSine (2000, 500);

elif isDictionary (input) and then input.what == "mute" then

    muteMixer (input.sender, input.parameter);

elif isDictionary (input) and then input.what == "playMusic" then

    playMusic = input.parameter;

elif isDictionary (input) and then input.what == "exitNow" then

    sysLog ("The voice room " + roomNumber + " has been broken by " + partyAddresses.(string (input.sender)));

    instantMessageContent = "The voice room " + roomNumber + " has been broken at " + objectToString (localTime ()) + " by " + partyAddresses.(string (input.sender));

    index = 0;
    while index < length (partyAddresses)     loop

        if partyAddresses.(partyAddresses[index]) == partyAddresses.(string (input.sender)) then

            void (sendInstantMessage (hostAddress, partyAddresses.(partyAddresses[index]), "You broke the voice room " + roomNumber + " at " + objectToString (localTime ())));

        else
            void (sendInstantMessage (hostAddress, 
partyAddresses.(partyAddresses[index]), instantMessageContent));
        end if;
        index = index + 1;

    end loop;
    exitNow = true;

elif isDictionary (input) and then input.what == "unknownEvent" then

    playSine (500, 100);

elif isDictionary (input) then

    sysLog ("Unexpected host task event in loop:" + input.what);

end if;

end loop;

void (detachMixer (null));
void (deactivateMeeting (null, roomNumber));

sysLog ("Voice room host task stopped normally");

end entry;


__________ Information from ESET NOD32 Antivirus, version of virus signature database 4765 (20100112) __________

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com Получено Thu Jan 14 18:39:30 2010

Этот архив был сгенерирован hypermail 2.1.8 : Fri 15 Jan 2010 - 00:16:06 MSK