sofaswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
October 2006
- 2 participants
- 9 discussions
30 Oct '06
Author: derek
Date: Sun Oct 29 20:58:23 2006
New Revision: 154
Modified:
sofaswitch/trunk/callflow/src/requestnode.cpp
Log:
Remove empty quotes from additional information field.
Modified: sofaswitch/trunk/callflow/src/requestnode.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/requestnode.cpp (original)
+++ sofaswitch/trunk/callflow/src/requestnode.cpp Sun Oct 29 20:58:23 2006
@@ -36,7 +36,7 @@
InformationSection(wxT("Timer label"), wxT("request node"));
displayData[displayData.size()] =
- InformationSection(wxT("Additional information (Python code)"), wxT("\"\""));
+ InformationSection(wxT("Additional information (Python code)"), wxT(""));
relInputPoints.Add(25, 0);
relOutputPoints.Add(25, 50);
1
0
28 Oct '06
Author: derek
Date: Sat Oct 28 03:42:51 2006
New Revision: 153
Modified:
sofaswitch/trunk/callflow/src/dnd.h
Log:
Reformat the list of kinds to a better syle of commenting for doxygen and
readability.
Modified: sofaswitch/trunk/callflow/src/dnd.h
==============================================================================
--- sofaswitch/trunk/callflow/src/dnd.h (original)
+++ sofaswitch/trunk/callflow/src/dnd.h Sat Oct 28 03:42:51 2006
@@ -250,28 +250,28 @@
/**The currently defined shapes that we can draw */
enum Kind
{
- /* 0 */ None /**The default kind, which is a placeholder, and is no shape at all */,
- /* 1 */ StartHere, /**Start processing here */
- /* 2 */ EndHere, /**Finish processing here */
- /* 3 */ StartFor /**Start of a for loop */,
- /* 4 */ EndFor /**End of a for loop */,
- /* 5 */ Conditional /**An If statement. This is the beginning - the end is handled by joining wires. */,
- /* 6 */ MakeCall /**Get a call started. In other words, start calling some entity outside of the building*/,
- /* 7 */ EndCall /**End a call. In other words, send a hangup message to the node */,
- /* 8 */ Select /**Used to indicate the rectangle on the screen we are selecting */,
- /* 9 */ JoinBlocks /**The multi line segment shape which joins two structures on the screen */,
- /* 10*/ Python /**The user can enter arbitary python here */,
- /* 11*/ RequestNode /**Query a supervisor for a node to use to talk on*/,
- /**12*/ Timer /**Initiate a timer, which runs for some specified time interval */,
- /**13*/ StopTimer /**Stop a running timer, so it will not generate an event etc */,
- /**14*/ Eventer /**Mark me as registering for an event. Possibly, wait for the registered for event */,
- /**15*/ TransferMedia /**Transfer media from one sofaswitch entity to another */,
- /**16*/ ReadFromFile /**Read audio from a .wav file (answering machine specific) */,
- /**17*/ WriteToFile /**Write audio into a .wav file (answering machine specific) */,
- /**18*/ LoadNewGraph /**Read in an existing graph file (pre compiled) for a new thread of exeuction */,
- /**19*/ SendDtmf /**Send a dtmf symbol to some sofaswitch worker node */,
- /**20*/ Death /**End all processing of this call flow now */,
- /* 21*/ KnownShapes /**Indicates the number of known shapes we can manage */
+ None = 0, /*!< The default kind, which is a placeholder, and is no shape at all */
+ StartHere = 1, /*!< Start processing here */
+ EndHere = 2, /*!< Finish processing here */
+ StartFor = 3, /*!< Start of a for loop */
+ EndFor = 4, /*!< End of a for loop */
+ Conditional = 5, /*!< An If statement. This is the beginning - the end is handled by joining wires. */
+ MakeCall = 6, /*!< Get a call started. In other words, start calling some entity outside of the building*/
+ EndCall = 7, /*!< End a call. In other words, send a hangup message to the node */
+ Select = 8, /*!< Used to indicate the rectangle on the screen we are selecting */
+ JoinBlocks = 9, /*!< The multi line segment shape which joins two structures on the screen */
+ Python = 10, /*!< The user can enter arbitary python here */
+ RequestNode = 11, /*!< Query a supervisor for a node to use to talk on*/
+ Timer = 12, /*!< Initiate a timer, which runs for some specified time interval */
+ StopTimer = 13, /*!< Stop a running timer, so it will not generate an event etc */
+ Eventer = 14, /*!< Mark me as registering for an event. Possibly, wait for the registered for event */
+ TransferMedia= 15, /*!< Transfer media from one sofaswitch entity to another */
+ ReadFromFile = 16, /*!< Read audio from a .wav file (answering machine specific) */
+ WriteToFile = 17, /*!< Write audio into a .wav file (answering machine specific) */
+ LoadNewGraph = 18, /*!< Read in an existing graph file (pre compiled) for a new thread of exeuction */
+ SendDtmf = 19, /*!< Send a dtmf symbol to some sofaswitch worker node */
+ Death = 20, /*!< End all processing of this call flow now */
+ KnownShapes = 21 /*!< Indicates the number of known shapes we can manage */
};
/**Constructor to a predefined shape */
1
0
28 Oct '06
Author: derek
Date: Sat Oct 28 03:02:50 2006
New Revision: 152
Modified:
sofaswitch/trunk/callflow/src/makecall.cpp
sofaswitch/trunk/callflow/src/requestnode.cpp
Log:
Add feature so that when requesting a worker node, you can supply
additional python arguements. Extend Makecall so that you specify the
destinaton as a python variable.
Modified: sofaswitch/trunk/callflow/src/makecall.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/makecall.cpp (original)
+++ sofaswitch/trunk/callflow/src/makecall.cpp Sat Oct 28 03:02:50 2006
@@ -22,9 +22,7 @@
{
displayData[displayData.size()] =
- InformationSection(wxT("Call destination (python code)"), wxT("\"h323:h323.voxgratia.org\""));
-
-
+ InformationSection(wxT("Call destination (Python code)"), wxT("\"h323:h323.voxgratia.org\""));
}
Modified: sofaswitch/trunk/callflow/src/requestnode.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/requestnode.cpp (original)
+++ sofaswitch/trunk/callflow/src/requestnode.cpp Sat Oct 28 03:02:50 2006
@@ -27,7 +27,7 @@
SetSize(newSize);
displayData[displayData.size()] =
- InformationSection(wxT("Request node from"), wxT("voip"));
+ InformationSection(wxT("Request node from (Python code)"), wxT("voip"));
displayData[displayData.size()] =
InformationSection(wxT("Timer period (seconds)"), wxT("1"));
@@ -35,6 +35,8 @@
displayData[displayData.size()] =
InformationSection(wxT("Timer label"), wxT("request node"));
+ displayData[displayData.size()] =
+ InformationSection(wxT("Additional information (Python code)"), wxT("\"\""));
relInputPoints.Add(25, 0);
relOutputPoints.Add(25, 50);
@@ -77,10 +79,11 @@
file.AddLine(" eName = self.data[a][\"Timer label\"] ");
file.AddLine(" self.pendingEvents[eName] = a ");
file.AddLine(" reactor.callLater(self.data[a][\"Timer period\"], self.timerObjectExpired, eName)");
- file.AddLine(" rhost = self.data[a][\"Request node from\"] ");
- file.AddLine(" rhost += \":REQUESTNEWID\\0\" ");
+ file.AddLine(" rhost = self.data[a][\"Request node from (Python code)\"] ");
+ file.AddLine(" rhost += \":REQUESTNEWID \" ");
+ file.AddLine(" rhost += eval(self.data[a][\"Additional info (Python code)\"]) + \"\\0\" ");
file.AddLine(" self.transport.write(rhost) ");
- file.AddLine(" return self.data[a][\"Output\"] ");
+ file.AddLine(" return self.data[a][\"Output\"] ");
file.AddLine("");
return true;
}
@@ -99,14 +102,21 @@
file.AddLine(wxString::Format(" \"Output\" : "));
file.AddLine(wxString::Format(" %s, ", outputLabel.c_str()));
+ wxString dest;
+ dest = ProtectString(displayData[1].data);
file.AddLine(wxString::Format(" \"Request node from\" : "));
- file.AddLine(wxString::Format(" \"%s\", ", displayData[1].data.c_str()));
+ file.AddLine(wxString::Format(" \"%s\", ", dest.c_str()));
file.AddLine(wxString::Format(" \"Timer period\" : "));
file.AddLine(wxString::Format(" %s, ", displayData[2].data.c_str()));
file.AddLine(wxString::Format(" \"Timer label\" : "));
file.AddLine(wxString::Format(" \"%s\", ", displayData[3].data.c_str()));
+
+
+ file.AddLine(wxString::Format(" \"Additional info\" : "));
+ dest = ProtectString(displayData[4].data);
+ file.AddLine(wxString::Format(" \"%s\", ", dest.c_str()));
file.AddLine(wxString::Format(" },"));
1
0
Author: derek
Date: Fri Oct 27 22:30:31 2006
New Revision: 151
Modified:
sofaswitch/trunk/mcu/conferenceroom.cxx
sofaswitch/trunk/mcu/manager.cxx
sofaswitch/trunk/mcu/manager.h
sofaswitch/trunk/mcu/member.cxx
sofaswitch/trunk/mcu/member.h
sofaswitch/trunk/mcu/participant.cxx
Log:
More tidyups. Move to nicer variable names, and fix PSafePtr issues,
and get threading closer to right.
Modified: sofaswitch/trunk/mcu/conferenceroom.cxx
==============================================================================
--- sofaswitch/trunk/mcu/conferenceroom.cxx (original)
+++ sofaswitch/trunk/mcu/conferenceroom.cxx Fri Oct 27 22:30:31 2006
@@ -84,26 +84,32 @@
PStringList ConferenceRoom::GetParticipantNames()
{
PWaitAndSignal m(memberListLock);
- PStringList participants = memberList;
+ PStringList participants;
+ for (PINDEX i = 0; i < memberList.GetSize(); i++)
+ participants += PString(memberList[i]);
+
PTRACE(3, "Participants in " << roomId << " is " << participants);
- return memberList;
+ return participants;
}
PStringList ConferenceRoom::AddNewMember(PString memberId)
{
PTRACE(3, "Add member " << memberId << " to " << roomId);
- PStringList currentMembers = memberList;
PWaitAndSignal m(memberListLock);
- currentMembers = memberList;
+ PStringList currentMembers;
+ for (PINDEX i = 0; i < memberList.GetSize(); i++)
+ currentMembers += PString(memberList[i]);
+
memberList.AppendString(memberId);
-
+
return currentMembers;
+
}
void ConferenceRoom::OnReleaseThreadMain(PThread &, INT)
{
- SafeDereference();
manager.RemoveConferenceRoomId(roomId);
+ SafeDereference();
}
void ConferenceRoom::Clear()
Modified: sofaswitch/trunk/mcu/manager.cxx
==============================================================================
--- sofaswitch/trunk/mcu/manager.cxx (original)
+++ sofaswitch/trunk/mcu/manager.cxx Fri Oct 27 22:30:31 2006
@@ -72,10 +72,10 @@
activeCalls.Initialise();
deadCommsInstances.Initialise();
- garbageCollector = PThread::Create(PCREATE_NOTIFIER(GarbageMain), 0,
- PThread::NoAutoDeleteThread,
- PThread::LowPriority,
- "purge Manager Lists");
+ PThread::Create(PCREATE_NOTIFIER(GarbageMain), 0,
+ PThread::AutoDeleteThread,
+ PThread::LowPriority,
+ "purge Manager Lists");
}
@@ -90,7 +90,9 @@
delete & supervisor;
- RemoveGarbageCollector();
+ garbageExit.Signal();
+
+ garbageFinished.Wait();
}
Comms * Manager::ClearCommsId(const PString &memberId)
@@ -125,13 +127,6 @@
return NULL;
}
-void Manager::RemoveGarbageCollector()
-{
- garbageExit.Signal();
- garbageCollector->WaitForTermination();
- delete garbageCollector;
-}
-
void Manager::GarbageMain(PThread &, INT)
{
while (!garbageExit.Wait(1000)) {
@@ -146,6 +141,7 @@
PTRACE(3, "Connections size is " << activeMembers.GetSize());
}
PTRACE(3, "Garbage exit can happen, as they are all gone ");
+ garbageFinished.Signal();
}
void Manager::CollectGarbage()
@@ -180,12 +176,18 @@
PSafePtr <Member> member =
activeMembers.FindWithLock(memberId, PSafeReadOnly);
if (member != NULL)
- member->RemoveFromRoom();
+ member->Clear();
}
+}
- PTRACE(3, "Remove MemberID \"" << memberId << "\" PARTIAL");
- activeMembers.RemoveAt(memberId);
- PTRACE(3, "Remove MemberID \"" << memberId << "\" DONE");
+void Manager::OnReleased(const PString & memberId)
+{
+ PTRACE(3, "Manager\tOnReleased " << memberId << " is now deleting");
+
+ if (activeMembers.FindWithLock(memberId, PSafeReadWrite) != NULL) {
+ PTRACE(3, "Manager\tOnReleased " << memberId << ".. Now do RemoveAt()");
+ activeMembers.RemoveAt(memberId);
+ }
}
@@ -199,36 +201,38 @@
{
PTRACE(3, "Manager\t request room " << cmd[1] << " and an id");
PString roomId = cmd[1];
- PSafePtr <ConferenceRoom> room;
{
PWaitAndSignal m(activeRooms.GetMutex()); /**Prevent adding two conferences of same name */
- room = activeRooms.FindWithLock(roomId, PSafeReadOnly);
+ PSafePtr <ConferenceRoom> room = activeRooms.FindWithLock(roomId, PSafeReadOnly);
if (room == NULL) { /*The room does not exist */
PTRACE(3, "Prior Create Conference room, size is " << activeRooms.GetSize());
PTRACE(3, "Create the room " << roomId << " in the conference server");
- room = new ConferenceRoom(*this, roomId);
- activeRooms.SetAt(roomId, room);
+ PSafePtr <ConferenceRoom > rm = new ConferenceRoom(*this, roomId);
+ activeRooms.SetAt(roomId, rm);
PTRACE(3, "Finished Create Conference room, size is " << activeRooms.GetSize());
} else {
PTRACE(3, "No need to create conference room " << roomId << " as it already exists");
}
}
+ PSafePtr <ConferenceRoom> room = activeRooms.FindWithLock(roomId, PSafeReadOnly);
+ if (room == NULL)
+ return;
+
Comms *c = runningComms->GetNextComms();
if (c == NULL)
return;
c->SetRemoteController(requester);
PTRACE(3, "Prior Create Member, size is " << activeMembers.GetSize());
- PSafePtr <Member> member = new Member(*this, room->GetRoomId(), c->GetOurId());
+ PSafePtr <Member> member = new Member(*this, roomId, c->GetOurId());
activeMembers.SetAt(c->GetOurId(), member);
PTRACE(3, "Have created member, " << c->GetOurId());
PStringList currentMembers = room->AddNewMember(c->GetOurId());
- FillMembershipList *f = new FillMembershipList(*this, currentMembers, c->GetOurId());
- f->Resume();
+ new FillMembershipList(*this, currentMembers, c->GetOurId());
PTRACE(3, "Have created member, " << c->GetOurId() << " and filled membership list");
nodesMakingCalls.AddNewMessageFrame(c);
Modified: sofaswitch/trunk/mcu/manager.h
==============================================================================
--- sofaswitch/trunk/mcu/manager.h (original)
+++ sofaswitch/trunk/mcu/manager.h Fri Oct 27 22:30:31 2006
@@ -156,14 +156,14 @@
void ThisFrameHasDied(MessageFrame *c)
{ deadCommsInstances.AddNewMessageFrame(c); }
+ /**Callback for removing a connection from the list of active
+ connections */
+ void OnReleased(const PString & memberId);
protected:
/**Go through the list of active calls, and tell them to "die now" */
void RemoveAllCalls();
-
- /**Remove and terminate the garbage collector thread */
- void RemoveGarbageCollector();
/**The interface to the external script which runs python, to provide comms for us */
LaunchNewId &lid;
@@ -219,13 +219,13 @@
/**@name Clean up dead activeMembers */
//@{
- /**The thread which runs every second to look for TCPConnections to delete */
- PThread *garbageCollector;
-
/**The syncpoint that flags when we exit, and is used to time the
1 second gaps between cleaning */
PSyncPoint garbageExit;
+ /**The syncpoint that the garbage collection thread fires on finishing. */
+ PSyncPoint garbageFinished;
+
/**The method which does the garbage collection */
void CollectGarbage();
Modified: sofaswitch/trunk/mcu/member.cxx
==============================================================================
--- sofaswitch/trunk/mcu/member.cxx (original)
+++ sofaswitch/trunk/mcu/member.cxx Fri Oct 27 22:30:31 2006
@@ -84,6 +84,8 @@
buffer = new BYTE[bufferSize];
memset(buffer, 0, bufferSize);
currentWriteIndex = 0;
+
+ isClearing = FALSE;
}
Member::~Member()
@@ -134,21 +136,6 @@
}
-void Member::RemoveFromRoom()
-{
- PTRACE(3, "Remove this member " << memberId
- << " from conference room " << roomId);
-
- keepGoing = FALSE;
-
- SafeReference(); //Guarantee this class won't be deleted "under our feet"
- PString name = "%X mdel " + memberId;
- PThread::Create(PCREATE_NOTIFIER(EmptyParticipantDict), 0,
- PThread::AutoDeleteThread,
- PThread::NormalPriority,
- name);
-}
-
void Member::DestroyThisParticipant(const PString &partyKey)
{
PTRACE(3, "Member " << memberId << " is now to remove participant " << partyKey);
@@ -278,6 +265,60 @@
dst_ptr++;
}
}
+
+void Member::Clear()
+{
+ {
+ PWaitAndSignal m(clearMutex);
+ if (isClearing)
+ return;
+ isClearing = TRUE;
+ }
+
+ PTRACE(3, *this << " is now doing a CLEAR for sure.");
+ // Add a reference for the thread we are about to start
+ SafeReference();
+ PString clearName = PString("OnRelease ") + memberId;
+ PThread::Create(PCREATE_NOTIFIER(OnReleaseThreadMain), 30000,
+ PThread::AutoDeleteThread,
+ PThread::NormalPriority,
+ clearName);
+}
+
+
+void Member::OnReleaseThreadMain(PThread &, INT)
+{
+ PTRACE(3, "OnRelease thread started for " << *this);
+
+ {
+ PSafePtr <ConferenceRoom> conferenceRoom = manager.GetConferenceRoom(roomId);
+ if (conferenceRoom != NULL) {
+ conferenceRoom->RemoveMember(memberId);
+ } else {
+ PTRACE(3, "ERROR Could not remove " << memberId << " from the conference room " );
+ PTRACE(3, roomId << "as " << roomId << " has gone");
+ }
+ }
+
+ participants.EmptyParticipantDict();
+ participants.WaitForTotallyEmpty();
+
+
+ OnReleased();
+
+ PTRACE(3, "Member\tOnRelease thread completed for " << *this);
+ // Dereference on the way out of the thread
+ SafeDereference();
+}
+
+
+void Member::OnReleased()
+{
+ PTRACE(3, "Member\tOnReleased " << *this);
+
+ manager.OnReleased(memberId);
+}
+
/////////////////////////////////////////////////////////////////////////////
MemberConsumer::MemberConsumer(Member *m)
:PThread(10000, AutoDeleteThread, LowPriority, "%X member delete"),
@@ -309,6 +350,7 @@
targetMemberId(_targetMemberId)
{
PTRACE(3, "Constructor:: " << *this);
+ Resume();
}
FillMembershipList::~FillMembershipList()
@@ -342,10 +384,10 @@
return;
for(PINDEX i = 0; i < membersToAdd.GetSize(); i++) {
- PSafePtr <Member> other = manager.GetMember(membersToAdd[i]);
- if ((other != NULL) && (other->GetMemberId() != targetMember->GetMemberId())) {
+ PSafePtr <Member> otherMember = manager.GetMember(membersToAdd[i]);
+ if ((otherMember != NULL) && (otherMember->GetMemberId() != targetMember->GetMemberId())) {
targetMember->AddMemberToRoom(membersToAdd[i]);
- other->AddMemberToRoom(targetMemberId);
+ otherMember->AddMemberToRoom(targetMemberId);
}
}
Modified: sofaswitch/trunk/mcu/member.h
==============================================================================
--- sofaswitch/trunk/mcu/member.h (original)
+++ sofaswitch/trunk/mcu/member.h Fri Oct 27 22:30:31 2006
@@ -91,9 +91,6 @@
members */
void AddMemberToRoom(const PString & newMember);
- /**Remove this member from the conference room*/
- void RemoveFromRoom();
-
/**A member of this conference room has ended.Consequently, the
Participant for that member has died. Since we point to that
member via a matching Participant, we have to remove that member
@@ -140,6 +137,10 @@
conference */
PString GetConferenceParticipants();
+ /**End this particular Member, This is the method to call, if you want this
+ Member to die good. */
+ void Clear();
+
protected:
/**Do the multiplexing of audio together */
@@ -198,6 +199,30 @@
/**The time at which this structure was created, which is the time this call
* was started at */
PTime memberCreatedAt;
+
+#ifdef DOC_PLUS_PLUS
+ /**This contains the 1 notifier that is used when closing down this
+ instance of TcpConnection class. It is called by a custom
+ thread, which deletes the class */
+ virtual void OnReleaseThreadMain(PThread &, INT);
+#else
+ PDECLARE_NOTIFIER(PThread, Member, OnReleaseThreadMain);
+#endif
+
+ /**Clean up the termination of the connection.
+ This function can do any internal cleaning up and waiting on background
+ threads that may be using the connection object.
+
+ The default behaviour calls the ConferenceServer function of the same name.
+ */
+ virtual void OnReleased();
+
+ /**Mutex to protect access to the isClearing flag, which ensures that only
+ one thread attempts to clear this connection */
+ PMutex clearMutex;
+
+ /**Flag to indicate we are being cleared, or have been cleared */
+ BOOL isClearing;
};
Modified: sofaswitch/trunk/mcu/participant.cxx
==============================================================================
--- sofaswitch/trunk/mcu/participant.cxx (original)
+++ sofaswitch/trunk/mcu/participant.cxx Fri Oct 27 22:30:31 2006
@@ -211,8 +211,14 @@
const PString & srcMember,
const PString & dstMember)
{
- PSafePtr <Member> dstMemberPtr = mgr.GetMember(dstMember);
- if (dstMemberPtr != NULL) {
+ {
+ PWaitAndSignal m(addNewParticipantMutex);
+ if (shuttingDown)
+ return;
+ }
+
+ PSafePtr <Member> dstMemberPtr = mgr.GetMember(dstMember);
+ if (dstMemberPtr != NULL) {
PSafePtr <Participant> participant = new Participant(mgr, *this, srcMember, dstMemberPtr);
SetAt(participant->GetKey(), participant);
@@ -222,13 +228,19 @@
void ParticipantDict::EmptyParticipantDict()
{
- PTRACE(3, "Start Empty participant list");
- PTRACE(3, "participant dict start with size of " << GetSize());
+ {
+ PWaitAndSignal m(addNewParticipantMutex);
+ if (shuttingDown)
+ return;
+ shuttingDown = TRUE;
+ }
- RemoveAll();
-
- PTRACE(3, "Done Empty participant list");
- PTRACE(3, "participant dict now has size of " << GetSize());
+ PTRACE(3, "Empty participantDict for Dictionary of \"" << *this << "\"");
+ for (PSafePtr<Participant> participant(*this, PSafeReadOnly); participant !=
+ NULL; ++participant) {
+ PTRACE(3, "Empty participant member " << *participant);
+ participant->Clear();
+ }
}
1
0
Author: derek
Date: Fri Oct 27 19:40:34 2006
New Revision: 150
Modified:
sofaswitch/trunk/mcu/manager.cxx
sofaswitch/trunk/mcu/manager.h
sofaswitch/trunk/mcu/member.cxx
sofaswitch/trunk/mcu/member.h
sofaswitch/trunk/mcu/participant.cxx
sofaswitch/trunk/mcu/participant.h
Log:
Add some better handling of the members in a participant dict.
Better use of PSafePtrs. More testing required.
Modified: sofaswitch/trunk/mcu/manager.cxx
==============================================================================
--- sofaswitch/trunk/mcu/manager.cxx (original)
+++ sofaswitch/trunk/mcu/manager.cxx Fri Oct 27 19:40:34 2006
@@ -173,7 +173,7 @@
supervisor.Resume();
}
-void Manager::RemoveMemberId(PString memberId)
+void Manager::RemoveMemberId(const PString & memberId)
{
PTRACE(3, "Remove MemberID \"" << memberId << "\" START");
{
@@ -189,7 +189,7 @@
}
-void Manager::RemoveConferenceRoomId(PString conferenceRoomId)
+void Manager::RemoveConferenceRoomId(const PString & conferenceRoomId)
{
PTRACE(3, "Remove conference room id from list of conference rooms " << conferenceRoomId);
activeRooms.RemoveAt(conferenceRoomId);
Modified: sofaswitch/trunk/mcu/manager.h
==============================================================================
--- sofaswitch/trunk/mcu/manager.h (original)
+++ sofaswitch/trunk/mcu/manager.h Fri Oct 27 19:40:34 2006
@@ -99,11 +99,11 @@
/**Cause the PSafePtr<Member> of the specified id to be removed from the
* activeMembers list in a threadsafe fashion */
- void RemoveMemberId(PString memberId);
+ void RemoveMemberId(const PString & memberId);
/**Cause the PSafePtr<ConferenceRoom> of the specified id to be
* removed from the activeRooms list in a threadsafe fashion */
- void RemoveConferenceRoomId(PString roomId);
+ void RemoveConferenceRoomId(const PString & roomId);
/**The entry point, where the main control loop sits */
void Main();
Modified: sofaswitch/trunk/mcu/member.cxx
==============================================================================
--- sofaswitch/trunk/mcu/member.cxx (original)
+++ sofaswitch/trunk/mcu/member.cxx Fri Oct 27 19:40:34 2006
@@ -78,7 +78,6 @@
IncCountMembers();
PTRACE(3, "Member\tConstructor " << *this);
- participants.SetAutoDeleteObjects();
keepGoing = TRUE;
bufferSize = PCM_BUFFER_SIZE;
@@ -129,15 +128,9 @@
return duration;
}
-void Member::AddMemberToRoom(PString newMember)
+void Member::AddMemberToRoom(const PString & newMember)
{
- PSafePtr <Member> member = manager.GetMember(newMember);
-
- if (member != NULL) {
- Participant *participant = new Participant(manager, memberId, member);
- participants.AddNewParticipant(participant);
- PTRACE(3, "Finished adding " << newMember << " to " << memberId);
- }
+ participants.AddNewParticipant(manager, memberId, newMember);
}
@@ -159,7 +152,7 @@
void Member::DestroyThisParticipant(const PString &partyKey)
{
PTRACE(3, "Member " << memberId << " is now to remove participant " << partyKey);
- participants.RemoveAt(partyKey);
+ participants.RemoveParticipant(partyKey);
}
Modified: sofaswitch/trunk/mcu/member.h
==============================================================================
--- sofaswitch/trunk/mcu/member.h (original)
+++ sofaswitch/trunk/mcu/member.h Fri Oct 27 19:40:34 2006
@@ -89,7 +89,7 @@
/**A new member has joined this conference room. This method is then
called to add the new member to this Members's list of other
members */
- void AddMemberToRoom(PString newMember);
+ void AddMemberToRoom(const PString & newMember);
/**Remove this member from the conference room*/
void RemoveFromRoom();
Modified: sofaswitch/trunk/mcu/participant.cxx
==============================================================================
--- sofaswitch/trunk/mcu/participant.cxx (original)
+++ sofaswitch/trunk/mcu/participant.cxx Fri Oct 27 19:40:34 2006
@@ -39,26 +39,31 @@
////////////////////////////////////////////////////////////////////////////////
-Participant::Participant(Manager & _mgr, const PString &baseMemberId, PSafePtr <Member> member)
+Participant::Participant(Manager & _mgr, ParticipantDict & _partyDict,
+ const PString &baseMemberId,
+ PSafePtr <Member> member)
: manager(_mgr),
- sourceMemberId(baseMemberId)
+ dictionary(_partyDict),
+ srcMemberId(baseMemberId)
{
- memberId = member->GetMemberId();
- SetKey (baseMemberId + PString("__") + memberId);
- SetMatchingKey(memberId + PString("__") + baseMemberId);
+ dstMemberId = member->GetMemberId();
+ SetKey (srcMemberId + PString("-->") + dstMemberId);
+ SetMatchingKey(dstMemberId + PString("-->") + srcMemberId);
+ isClearing = FALSE;
memberPtr = member;
PTRACE(3, "Participant\tConstructor " << *this);
- memberPtr->SafeReference();
currentReadIndex = 0;
IncCountParticipants();
+ dictionary.ParticipantCreated();
}
Participant::~Participant()
{
- DecCountParticipants();
- PTRACE(3, "Participant\tDestructor " << *this);
- new MatchingParticipantConsumer(memberPtr, GetMatchingKey());
+ DecCountParticipants();
+
+ PTRACE(3, "Participant " << *this << " destroyed dead and gone");
+ dictionary.ParticipantDestroyed();
}
void Participant::PrintOn(ostream & strm /// Stream to output text representation
@@ -69,7 +74,7 @@
PString Participant::GetMemberId()
{
- return memberId;
+ return srcMemberId;
}
BOOL Participant::ReadAndMixAudio(BYTE * data, PINDEX amount)
@@ -77,8 +82,52 @@
return memberPtr->ReadAndMixAudio(data, amount, currentReadIndex);
}
+void Participant::OnReleased()
+{
+ dictionary.ParticipantReleased(GetKey());
+}
+
+
+void Participant::Clear()
+{
+ PTRACE(3, *this << " has been told to CLEAR");
+ {
+ PWaitAndSignal m(clearMutex);
+ if (isClearing)
+ return;
+ isClearing = TRUE;
+ }
+ // Add a reference for the thread we are about to start
+ SafeReference();
+ PString clearName = PString("OnRelease ") + GetKey();
+ PThread::Create(PCREATE_NOTIFIER(OnReleaseThreadMain), 30000,
+ PThread::AutoDeleteThread,
+ PThread::NormalPriority,
+ clearName);
+}
+
+
+void Participant::OnReleaseThreadMain(PThread &, INT)
+{
+ PTRACE(3, "OnRelease thread started for " << *this);
+
+ DestroyNeighboursLink();
+
+ OnReleased();
+
+ PTRACE(3, "Participant OnRelease thread completed for " << *this);
+ // Dereference on the way out of the thread
+ SafeDereference();
+}
+
+void Participant::DestroyNeighboursLink()
+{
+ new MatchingParticipantConsumer(manager, dstMemberId, GetMatchingKey());
+}
+
+
////////////////////////////////////////////////////////////////////////////////
-void ParticipantDict::DeleteObject(PObject * object) const
+void ParticipantD::DeleteObject(PObject * object) const
{
Participant * oneParticipant = PDownCast(Participant, object);
if (oneParticipant != NULL) {
@@ -87,6 +136,58 @@
}
}
+/////////////////////////////////////////////////////////////////////////////
+ParticipantDict::ParticipantDict()
+{
+ countEntries = 0;
+ SetAutoDeleteObjects();
+
+ shuttingDown = FALSE;
+ PString name = psprintf("garbage %x", this);
+ PThread::Create(PCREATE_NOTIFIER(GarbageMain), 0,
+ PThread::AutoDeleteThread,
+ PThread::LowPriority,
+ name);
+}
+
+ParticipantDict::~ParticipantDict()
+{
+ WaitForTotallyEmpty();
+
+ garbageCollectExit.Signal();
+ garbageFinished.Wait();
+}
+
+
+void ParticipantDict::GarbageMain(PThread &, INT)
+{
+ while (!garbageCollectExit.Wait(500))
+ GarbageCollection();
+
+ garbageFinished.Signal();
+}
+
+
+void ParticipantDict::GarbageCollection()
+{
+ DeleteObjectsToBeRemoved();
+ PTRACE(5, "Garbage on ParticipantDict done, remaining, " << GetSize());
+}
+
+void ParticipantDict::WaitForTotallyEmpty()
+{
+ while (countEntries > 0) {
+ PThread::Sleep(500);
+ }
+}
+
+void ParticipantDict::PrintOn(ostream & strm /// Stream to output text representation
+ ) const
+{
+ for (PSafePtr<Participant> participant(*this, PSafeReadOnly); participant != NULL; ++participant)
+ strm << participant->GetKey() << " ";
+}
+
PSortedStringList ParticipantDict::GetConferenceParticipants()
{
PSortedStringList res;
@@ -99,20 +200,24 @@
void ParticipantDict::ReadAndMixAudio(BYTE *data, PINDEX amount)
{
- for (PSafePtr<Participant> participant(*this, PSafeReadOnly); participant != NULL; ++participant) {
- BOOL readStatus = participant->ReadAndMixAudio(data, amount);
- if (!readStatus) {
- PTRACE(3, "Remove participant from list " << *participant);
- RemoveAt(participant->GetKey());
+ for (PSafePtr<Participant> participant(*this, PSafeReadOnly); participant != NULL; ++participant) {
+ BOOL readStatus = participant->ReadAndMixAudio(data, amount);
+ if (!readStatus)
+ participant->Clear();
}
- }
}
-
-void ParticipantDict::AddNewParticipant(PSafePtr<Participant> src)
+void ParticipantDict::AddNewParticipant(Manager & mgr,
+ const PString & srcMember,
+ const PString & dstMember)
{
- PTRACE(3, "Add new participant of " << src->GetMemberId());
- SetAt(src->GetKey(), src);
+ PSafePtr <Member> dstMemberPtr = mgr.GetMember(dstMember);
+ if (dstMemberPtr != NULL) {
+ PSafePtr <Participant> participant = new Participant(mgr, *this, srcMember, dstMemberPtr);
+ SetAt(participant->GetKey(), participant);
+
+ PTRACE(3, "Done add new participant of " << participant->GetKey());
+ }
}
void ParticipantDict::EmptyParticipantDict()
@@ -127,44 +232,51 @@
}
-void ParticipantDict::RemoveParticipant(PString member)
+void ParticipantDict::RemoveParticipant(const PString & member)
{
PTRACE(3, "RemoveParticipant for " << member);
- for (PSafePtr<Participant> participant(*this, PSafeReadWrite); participant != NULL; ++participant) {
- if (participant->GetMemberId() == member) {
- PString tempKey = participant->GetKey();
- PTRACE(3, "Start Remove participant from list " << member << " and " << tempKey);
- RemoveAt(participant->GetKey());
- PTRACE(3, "Finished Remove participant from list " << member << " and " << tempKey);
- return;
+ PSafePtr<Participant> participant = FindWithLock(member, PSafeReadOnly);
+ if (participant != NULL)
+ participant->Clear();
+}
+
+void ParticipantDict::ParticipantReleased(const PString & partKey)
+{
+ PSafePtr<Participant> participant = FindWithLock(partKey, PSafeReadWrite);
+ if (participant != NULL) {
+ PTRACE(3, "Participant OnReleased " << partKey << ".. Now do RemoveAt()");
+ RemoveAt(partKey);
}
- PTRACE(3, "Did not find participant " << member << " in list");
- }
}
/////////////////////////////////////////////////////////////////////////////
-MatchingParticipantConsumer::MatchingParticipantConsumer(Member *m, const PString & _key)
+MatchingParticipantConsumer::MatchingParticipantConsumer(Manager & _mgr,
+ const PString & _otherMember,
+ const PString & _partyKey)
:PThread(10000, AutoDeleteThread, LowPriority, "%X participantdelete"),
- member(m), key(_key)
+ mgr(_mgr),
+ otherMember(_otherMember),
+ partyKey(_partyKey)
{
- PTRACE(3, "ParticipantConsumer contructor " << key);
+ PTRACE(3, "ParticipantConsumer contructor " << partyKey);
Resume();
}
MatchingParticipantConsumer::~MatchingParticipantConsumer()
{
- PTRACE(3, "ParticipantConsumer destructor " << key);
+ PTRACE(3, "ParticipantConsumer destructor " << partyKey);
}
void MatchingParticipantConsumer::Main()
{
- if (member == NULL)
- return;
+ PSafePtr <Member> member = mgr.GetMember(otherMember);
+
+ if (member == NULL)
+ return;
- member->DestroyThisParticipant(key);
- member->SafeDereference();
+ member->DestroyThisParticipant(partyKey);
}
Modified: sofaswitch/trunk/mcu/participant.h
==============================================================================
--- sofaswitch/trunk/mcu/participant.h (original)
+++ sofaswitch/trunk/mcu/participant.h Fri Oct 27 19:40:34 2006
@@ -40,32 +40,51 @@
////////////////////////////////////////////////////////////////////////////////
-
/**The thread safe list of Participants to each conference */
-class ParticipantDict : public PSafeDictionary<PString, Participant>
+class ParticipantD : public PSafeDictionary<PString, Participant>
{
/**One function that we have to define for this usage, and that
is the deletion of existing members. PWLib will have removed
the object to be deleted from the list. We simply need to
delete it. */
virtual void DeleteObject(PObject * object) const;
-
+};
+/////////////////////////////////////////////////////////////////////////////
+
+/**The thread safe list of Participants to each conference. This class is
+ descended off ParticipantD, and gives us a chance to put a constructor
+ in. */
+class ParticipantDict : ParticipantD
+{
public:
- /**Step through the list, and do a ReadAndMix audio process on each of
- them. */
- void ReadAndMixAudio(BYTE *data, PINDEX amount);
+ /**Constructor, which creates the garbage cleaning thread, and turns on
+ auto deleteion of objects */
+ ParticipantDict();
- /**Add an instance of the Participant class (supplied as an argument)
- to the end of this list*/
- void AddNewParticipant(PSafePtr<Participant> src);
+ /**Destructor. Wait for this dictionary to be totally empty, and then
+ stop the garbage collection,*/
+ ~ParticipantDict();
- /**Remove the participant matching the specified member id*/
- void RemoveParticipant(PString _memberId);
-
- /**Get the names of the members in this conference */
- PSortedStringList GetConferenceParticipants();
-
- /**Tell each of the members in this list to go away and die. When
+ /**pretty print information in this class. It lists all the
+ current keys in this class. */
+ virtual void PrintOn(ostream & strm /// Stream to output text representation
+ ) const;
+
+ /**Step through the list, and do a ReadAndMix audio process on each of
+ them. */
+ void ReadAndMixAudio(BYTE *data, PINDEX amount);
+
+ /**Add an instance of the Participant class to the end of this list. If we
+ cannot find the requiste member to add, just do nothing.*/
+ void AddNewParticipant(Manager & mgr, const PString & srcMember, const PString & dstMember);
+
+ /**Remove the participant matching the specified member id*/
+ void RemoveParticipant(const PString & _memberId);
+
+ /**Get the names of the members in this conference */
+ PSortedStringList GetConferenceParticipants();
+
+ /**Tell each of the members in this list to go away and die. When
each Participant is destroyed (which it will do since we are the
only ones who know about a participant, the destructor of that
Participant will cause the matching Participant to be destroyed.
@@ -84,7 +103,57 @@
there will be no participants in this dictionary. The reason is that
a Participant links from one Member to another Member.
*/
- void EmptyParticipantDict();
+
+ void EmptyParticipantDict();
+
+/**Wait for this class to go totally empty, with zero entries in it. */
+ void WaitForTotallyEmpty();
+
+ /**A particpant calls this method when the participant is
+ constructed. This method is used to keep track of the number of
+ participant instances in this dictionary. */
+ void ParticipantCreated() { ++countEntries; }
+
+ /**A particpant calls this method when the participant is
+ deleted. This method is used to keep track of the number of
+ participant instances in this dictionary. */
+ void ParticipantDestroyed() { ++countEntries; }
+
+ /**A participant has gone through it's clear process, and now needs to
+ advise this dictionary that it has been released */
+ void ParticipantReleased(const PString & partKey);
+
+ /**The method used to invoke the cleaning up of old Participants in this
+ dictionary */
+ void GarbageCollection();
+
+ protected:
+ /**Mutex to protect access to the shuttingDown flag */
+ PMutex addNewParticipantMutex;
+
+ /**Flag to indicate we are closing this participant dictionary, so prevent t
+he
+ adding of more members to this dictionary */
+ BOOL shuttingDown;
+
+ /**The flag used to time the tests of the garbage collector, and to signal
+ * its demise */
+ PSyncPoint garbageCollectExit;
+
+ /**The flag used to signal the demise of the garbage collector */
+ PSyncPoint garbageFinished;
+
+#ifdef DOC_PLUS_PLUS
+ /**The garbage collector runs this method to do garbage collection */
+ virtual void GarbageMain(PThread &, INT);
+#else
+ PDECLARE_NOTIFIER(PThread, ParticipantDict, GarbageMain);
+#endif
+
+ private:
+ /**Count of the additions/deleteions to this class */
+ PAtomicInteger countEntries;
+
};
/////////////////////////////////////////////////////////////////////////////
@@ -116,6 +185,7 @@
/**Constructor, which creates this member, who has link to the manger
and knows the conference we are a part of */
Participant(Manager & _mgr,
+ ParticipantDict & partDict,
const PString &baseMember,
PSafePtr <Member> member);
@@ -151,10 +221,41 @@
to and the member who created us. */
PString GetMatchingKey() const { return matchingKey; }
+ /**End this particular Participant, and remove it dead. Do notifiy the
+ ParticipantDict this Participant is stored in. This is the method to
+ call, if you want this Participant to die. */
+ void Clear();
+
protected:
+#ifdef DOC_PLUS_PLUS
+ /**This contains the 1 notifier that is used when closing down this
+ instance of Participant class. It is called by a custom
+ thread, which deletes the class */
+ virtual void OnReleaseThreadMain(PThread &, INT);
+#else
+ PDECLARE_NOTIFIER(PThread, Participant, OnReleaseThreadMain);
+#endif
+
+ /**Clean up the termination of this Participant. This function can do any
+ internal cleaning up and waiting on background threads that may be
+ using the connection object.
+
+ The default behaviour calls the ParticipantDict function of the same
+ name.
+ */
+ virtual void OnReleased();
+
+ /**Destroy the link from us to the other. This causees the other to
+ quietly destroy its link to us, but not tell us it has died */
+ void DestroyNeighboursLink();
+
+
/**link to the manager, who knows everything about everything */
Manager & manager;
+ /**Link to the participant dict who will hold this participant */
+ ParticipantDict & dictionary;
+
/**Set the key which this participant is known by. The key
describes the id of the member who created us, and the member we
are connected to. The Key is set in the constructor of this class. */
@@ -169,24 +270,33 @@
PINDEX currentReadIndex;
/**The remote member that we are connected to */
- Member * memberPtr;
+ PSafePtr <Member> memberPtr;
/**The id of the Member who will use us to link to memberId */
- PString sourceMemberId;
+ PString srcMemberId;
/**The id of the member we link to */
- PString memberId;
+ PString dstMemberId;
/**The key by which this participant is known by. The key describes
the id of the member who created us, and the member we are
- connected to. The key is a concatanation of the sourceMemberId
- and the memberId */
+ connected to. The key is a concatanation of the srcMemberId
+ and the dstMemberId */
PString key;
/**The m key by which the corresponding participant to us is
known by. The key describes the id of the member we are connected
to and the member who created us. */
PString matchingKey;
+
+ /**Mutex to protect access to the isClearing flag, which ensures that only
+ one thread attempts to clear this participant */
+ PMutex clearMutex;
+
+ /**Flag to indicate we are being cleared, or have been cleared. Thus, if
+ two threads call Clear at the same time, only one thread is created to
+ do the clearing. */
+ BOOL isClearing;
};
/////////////////////////////////////////////////////////////////////////////
@@ -202,7 +312,9 @@
/**Constructor - create this class, which is given the class to destroy.
This class then does the rest */
- MatchingParticipantConsumer(Member *m, const PString & _key);
+ MatchingParticipantConsumer(Manager & _mgr,
+ const PString &_otherMember,
+ const PString & _partyKey);
/**Destructor. */
~MatchingParticipantConsumer();
@@ -211,13 +323,15 @@
void Main();
protected:
-
+ /**Reference to the manager of this conference */
+ Manager & mgr;
+
/**The instance we have to talk to, so the matching Participant
class can be deleted */
- Member *member;
+ PString otherMember;
/**The key of the matching Participant class we want to delete */
- PString key;
+ PString partyKey;
};
#endif // _Mcu_Participant_H
1
0
18 Oct '06
Author: sphere
Date: Wed Oct 18 03:39:26 2006
New Revision: 149
Added:
sofaswitch/branches/manprit_aurora/
Log:
Creating empty folder for manprit_aurora
1
0
[Sofaswitch-svn] [commit] r148 - in sofaswitch/trunk: . callflow/src callflow/tests prompts sofa/include/sofa sofa/src
by SofaSWITCH SVN 10 Oct '06
by SofaSWITCH SVN 10 Oct '06
10 Oct '06
Author: derek
Date: Tue Oct 10 16:48:03 2006
New Revision: 148
Added:
sofaswitch/trunk/callflow/tests/amplaywavfile.src
sofaswitch/trunk/callflow/tests/loadgraph.src
Modified:
sofaswitch/trunk/callflow/src/callstartstop.cpp
sofaswitch/trunk/callflow/src/conditional.cpp
sofaswitch/trunk/callflow/src/death.cpp
sofaswitch/trunk/callflow/src/fileio.cpp
sofaswitch/trunk/callflow/src/loadnewgraph.cpp
sofaswitch/trunk/callflow/src/readfromfile.cpp
sofaswitch/trunk/callflow/src/shapelist.cpp
sofaswitch/trunk/callflow/src/shapelist.h
sofaswitch/trunk/callflow/src/writetofile.cpp
sofaswitch/trunk/message.cxx
sofaswitch/trunk/prompts/instructions.wav
sofaswitch/trunk/sofa/include/sofa/messages.h
sofaswitch/trunk/sofa/src/messages.cxx
Log:
updates, new instructions,
Modified: sofaswitch/trunk/callflow/src/callstartstop.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/callstartstop.cpp (original)
+++ sofaswitch/trunk/callflow/src/callstartstop.cpp Tue Oct 10 16:48:03 2006
@@ -31,7 +31,7 @@
InformationSection(wxT("Worker node to activate (python code)"), wxT("\"voip1\""));
else
displayData[displayData.size()] =
- InformationSection(wxT("Worker node to close call (python code)"), wxT("\"voip1\""));
+ InformationSection(wxT("Worker node for termination (python code)"), wxT("\"voip1\""));
AdjustIoPoints();
}
Modified: sofaswitch/trunk/callflow/src/conditional.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/conditional.cpp (original)
+++ sofaswitch/trunk/callflow/src/conditional.cpp Tue Oct 10 16:48:03 2006
@@ -36,6 +36,7 @@
{
DrawCompileError(dc);
dc.SetPen(*wxBLACK_PEN);
+ dc.SetBrush(wxBrush(*wxBLACK, wxSOLID));
wxPoint p1(m_rect.GetPosition());
wxPoint pA(p1.x + 25, p1.y + 35);
Modified: sofaswitch/trunk/callflow/src/death.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/death.cpp (original)
+++ sofaswitch/trunk/callflow/src/death.cpp Tue Oct 10 16:48:03 2006
@@ -19,10 +19,10 @@
DndShapeDeath::DndShapeDeath()
: DndShape(Death)
{
- wxSize newSize(50, 40);
+ wxSize newSize(24, 40);
SetSize(newSize);
- relInputPoints.Add(25, 0);
+ relInputPoints.Add(12, 0);
AdjustIoPoints();
skullBitmap = wxBitmap(death);
@@ -35,25 +35,28 @@
dc.SetBrush(wxBrush(*wxBLACK, wxSOLID));
wxPoint p1(m_rect.GetPosition());
- wxPoint pA(p1.x + 25, p1.y + 15);
- wxPoint pB(p1.x + 25, p1.y + 0);
- wxPoint pC(p1.x + 25, p1.y + 10);
+ wxPoint pA(p1.x + 12, p1.y + 15);
+ wxPoint pB(p1.x + 12, p1.y + 0);
+ wxPoint pC(p1.x + 12, p1.y + 10);
dc.DrawLine(pA, pB);
DrawArrow(dc, pC, ArrowDown, InputPointConnected(0) ? Connected : Loose);
- dc.DrawBitmap(skullBitmap, p1.x + 13, p1.y + 15, true);
+ dc.DrawBitmap(skullBitmap, p1.x + 00, p1.y + 15, true);
DndShape::Draw(dc);
}
bool DndShapeDeath::WriteSystemCode(wxTextFile & file)
{
- file.AddLine(" def Death(self, sTuple): ");
- file.AddLine(" \"\"\"Terminate processing of this flow chart, by closing this whole thing down ");
- file.AddLine(" \"\"\" ");
- file.AddLine(" reactor.disconnectAll() ");
- file.AddLine(" return None ");
- file.AddLine(" ");
+ file.AddLine(" def Death(self, sTuple): ");
+ file.AddLine(" \"\"\"Terminate processing of this flow chart, by closing this particular connection. ");
+ file.AddLine(" \"\"\" ");
+ file.AddLine(" if self.isMaster: ");
+ file.AddLine(" reactor.disconnectAll() ");
+ file.AddLine(" else: ");
+ file.AddLine(" self.transport.loseConnection() ");
+ file.AddLine(" return None ");
+ file.AddLine(" ");
return true;
}
Modified: sofaswitch/trunk/callflow/src/fileio.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/fileio.cpp (original)
+++ sofaswitch/trunk/callflow/src/fileio.cpp Tue Oct 10 16:48:03 2006
@@ -97,10 +97,12 @@
file.AddLine(wxString::Format(" %s, ", outputLabel.c_str()));
file.AddLine(wxString::Format(" \"File Name\" : "));
- file.AddLine(wxString::Format(" \"%s\", ", displayData[1].data.c_str()));
+ wxString dest = ProtectString(displayData[1].data);
+ file.AddLine(wxString::Format(" \"%s\", ", dest.c_str()));
file.AddLine(wxString::Format(" \"answering machine node\" : "));
- file.AddLine(wxString::Format(" \"%s\", ", displayData[2].data.c_str()));
+ dest = ProtectString(displayData[2].data);
+ file.AddLine(wxString::Format(" \"%s\", ", dest.c_str()));
file.AddLine(wxString::Format(" },"));
Modified: sofaswitch/trunk/callflow/src/loadnewgraph.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/loadnewgraph.cpp (original)
+++ sofaswitch/trunk/callflow/src/loadnewgraph.cpp Tue Oct 10 16:48:03 2006
@@ -27,7 +27,7 @@
relOutputPoints.Add(25, 50);
displayData[displayData.size()] =
- InformationSection(wxT("new graph file"), wxT("some_file"));
+ InformationSection(wxT("new graph file (Python code)"), wxT("\"file_graph\""));
AdjustIoPoints();
}
@@ -66,10 +66,14 @@
bool DndShapeLoadNewGraph::WriteSystemCode(wxTextFile & file)
{
- file.AddLine(" def LoadNewGraph(self, sTuple): ");
- file.AddLine(" a,b,c = sTuple");
- file.AddLine(" exec(self.data[a][\"LoadNewGraph Code\"])");
- file.AddLine(" return self.data[a][\"Output\"]");
+ file.AddLine(" def Load_New_Graph(self, sTuple): ");
+ file.AddLine(" a,b,c = sTuple ");
+ file.AddLine(" fname = eval(self.data[a][\"new graph file\"]) ");
+ file.AddLine(" f = MyFactory() ");
+ file.AddLine(" f.isMaster = False ");
+ file.AddLine(" f.setGraph(fname) ");
+ file.AddLine(" reactor.connectTCP(sofaServer, 5000, f) ");
+ file.AddLine(" return self.data[a][\"Output\"] ");
file.AddLine("");
return true;
@@ -90,7 +94,8 @@
file.AddLine(wxString::Format(" %s, ", outputLabel.c_str()));
file.AddLine(wxString::Format(" \"new graph file\" : "));
- file.AddLine(wxString::Format(" \"%s\", ", displayData[1].data.c_str()));
+ wxString dest = ProtectString(displayData[1].data);
+ file.AddLine(wxString::Format(" \"%s\", ", dest.c_str()));
file.AddLine(wxString::Format(" },"));
Modified: sofaswitch/trunk/callflow/src/readfromfile.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/readfromfile.cpp (original)
+++ sofaswitch/trunk/callflow/src/readfromfile.cpp Tue Oct 10 16:48:03 2006
@@ -24,11 +24,11 @@
SetSize(newSize);
displayData[displayData.size()] =
- InformationSection(wxT("Filename to read audio from"), wxT("src_audio.wav"));
+ InformationSection(wxT("Filename to read audio from (Python code)"), wxT("\"src_audio.wav\""));
displayData[displayData.size()] =
- InformationSection(wxT("answering machine node"), wxT("Answering machine worker node"));
+ InformationSection(wxT("answering machine node (Python code)"), wxT("Answering machine worker node"));
relInputPoints.Add(25, 0);
relOutputPoints.Add(25, 50);
Modified: sofaswitch/trunk/callflow/src/shapelist.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/shapelist.cpp (original)
+++ sofaswitch/trunk/callflow/src/shapelist.cpp Tue Oct 10 16:48:03 2006
@@ -184,7 +184,9 @@
int index = graphName.Find(".");
if (index >= 0)
graphName = graphName.Left(index);
- graphName = graphName + "_graph";
+ graphName = graphName + ".graph";
+ graphFileName = graphName;
+
wxTextFile graphFile(graphName);
if (!graphFile.Exists())
graphFile.Create();
@@ -298,6 +300,7 @@
file.AddLine(" ");
file.AddLine(" \"\"\" ");
file.AddLine(" def __init__(self): ");
+ file.AddLine(" self.isMaster = True ");
file.AddLine(" self.graphSet = False ");
file.AddLine(" self.connectionIsMade = False ");
file.AddLine(" self.endProgramNow = False ");
@@ -467,7 +470,7 @@
file.AddLine(" initialise, and activate the next step of initialise. Or, it is an ordinary ");
file.AddLine(" message that has to be processed ");
file.AddLine(" \"\"\" ");
- file.AddLine(" print \"Received the message \", data ");
+ file.AddLine(" #print \"Received the message \", data ");
file.AddLine(" while data.find(\" \") >= 0: ");
file.AddLine(" data = data.replace(\" \", \" \") ");
file.AddLine(" ssdata = str(data).split(\'\\0\') ");
@@ -520,11 +523,10 @@
file.AddLine(" protocol = Controller ");
file.AddLine(" ");
file.AddLine(" def clientConnectionFailed(self, connector, reason): ");
- file.AddLine(" print \"Connection failed - goodbye!\" ");
- file.AddLine(" reactor.stop() ");
+ file.AddLine(" self.zzzzzzz = reason ");
file.AddLine(" ");
file.AddLine(" def clientConnectionLost(self, connector, reason): ");
- file.AddLine(" reactor.stop() ");
+ file.AddLine(" self.zzzzzzzz = reason ");
file.AddLine(" ");
file.AddLine(" def buildProtocol(self, addr): ");
file.AddLine(" p = self.protocol() ");
@@ -532,18 +534,12 @@
file.AddLine(" self.myController = p ");
file.AddLine(" self.myController.setGraphData(self.myGraphName) ");
file.AddLine(" return p ");
- file.AddLine(" for key in dir(p): ");
- file.AddLine(" if '__' not in key: ");
- file.AddLine(" value = getattr(p,key) ");
- file.AddLine(" print key ");
- file.AddLine(" print key, \" \", value ");
- file.AddLine(" return p ");
file.AddLine(" ");
file.AddLine(" def setGraph(self, newName): ");
file.AddLine(" self.myGraphName = newName ");
file.AddLine(" ");
file.AddLine("f = MyFactory() ");
- file.AddLine("f.setGraph(\"a_graph\") ");
+ file.AddLine(wxString::Format("f.setGraph(\"%s\") ", graphFileName.c_str()));
file.AddLine("reactor.connectTCP(sofaServer, 5000, f) ");
file.AddLine("reactor.run() ");
file.AddLine(" ");
Modified: sofaswitch/trunk/callflow/src/shapelist.h
==============================================================================
--- sofaswitch/trunk/callflow/src/shapelist.h (original)
+++ sofaswitch/trunk/callflow/src/shapelist.h Tue Oct 10 16:48:03 2006
@@ -81,6 +81,11 @@
which match these coordinates. If there is a match found, mark
them accordingly */
void LookForMatchingShapes(const wxPoint & firstPoint, const wxPoint & lastPoint);
+
+ /**The name of the graph file, generated as part of the compile process. If
+ the source name is load.py, the graph name will be load.graph. If the
+ source name is example, the graph name will be example.graph.*/
+ wxString graphFileName;
};
Modified: sofaswitch/trunk/callflow/src/writetofile.cpp
==============================================================================
--- sofaswitch/trunk/callflow/src/writetofile.cpp (original)
+++ sofaswitch/trunk/callflow/src/writetofile.cpp Tue Oct 10 16:48:03 2006
@@ -24,11 +24,11 @@
SetSize(newSize);
displayData[displayData.size()] =
- InformationSection(wxT("Filename to contain new audio"), wxT("empty_file.wav"));
+ InformationSection(wxT("Filename to contain new audio (Python code)"), wxT("\"empty_file.wav\""));
displayData[displayData.size()] =
- InformationSection(wxT("answering machine node"), wxT("Answering machine worker node"));
+ InformationSection(wxT("answering machine node (Python code)"), wxT("Answering machine worker node"));
relInputPoints.Add(25, 0);
relOutputPoints.Add(25, 50);
Added: sofaswitch/trunk/callflow/tests/amplaywavfile.src
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/callflow/tests/amplaywavfile.src Tue Oct 10 16:48:03 2006
@@ -0,0 +1,3 @@
+9<B>632<B>318<B>632,366,638,319,685,318,685,330<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>821<B>356<B>821,357,977,357,1018,356<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>1<B>190<B>19<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>9<B>544<B>394<B>606,394,602,560,544,561<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>5<B>241<B>359<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>(self.amNode != None) and (self.soundNode != None)<ms><special> <B><Shape>17<B>516<B>509<B> extra <special>Tool Tip<ms>Write To File<ms><special>Filename to contain new audio (Python code)<ms>"recorded_audio.wav"<ms><special>answering machine node<ms>self.amNode<ms><special> <B><Shape>15<B>989<B>451<B> extra <special>Tool Tip<ms>Transfer Media<ms><special>First SofaSwitch worker (python)<ms>"sound"<ms><special>Second SofaSwitch worker (python)<ms>"sound"<ms><special> <B><Shape>14<B>202<B>162<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>amREQ<ms><special>Python variable to hold event data<ms>self.amNode<ms><special> <B><Shape>2<B>307<B>394<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>14<B>295<B>185<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>soundREQU<ms><special>Python variable to hold event data<ms>self.soundNode<ms><special> <B><Shape>9<B>559<B>339<B>559,339,604,342<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>16<B>516<B>561<B> extra <special>Tool Tip<ms>initial wav file<ms><special>Filename to read audio from (Python code)<ms>"../prompts/instructions.wav"<ms><special>answering machine node<ms>self.amNode<ms><special> <B><Shape>20<B>529<B>662<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>9<B>712<B>318<B>712,358,755,361,750,320,793,318,798,333<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>16<B>505<B>364<B> extra <special>Tool Tip<ms>Read From File<ms><special>Filename to read audio from (Python code)<ms>"../prompts/sample_message.wav"<ms><special>answering machine node<ms>self.amNode<ms><special> <B><Shape>5<B>991<B>358<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>self.dtmfData=="9"<ms><special> <B><Shape>10<B>990<B>405<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "hangup, as dtmf 9 has been received"<ms><special> <B><Shape>9<B>266<B>329<B>308,329,266,359<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>2<B>505<B>398<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>9<B>264<B>199<B>264,513,264,635,426,639,428,199,532,202,532,262<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>13<B>190<B>210<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>request voip<ms><special> <B><Shape>10<B>190<B>254<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "Have a new am node on ", self.amNode<ms><special> <B><Shape>13<B>284<B>231<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>request sound<ms><special> <B><Shape>15<B>240<B>412<B> extra <special>Tool Tip<ms>Transfer Media<ms><special>First SofaSwitch worker (python)<ms>self.amNode<ms><special>Second SofaSwitch worker (python)<ms>self.soundNode<ms><special> <B><Shape>9<B>302<B>485<B>302,485,544,492,542,506<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>5<B>770<B>331<B> extra <special>Tool Tip<ms>play leaving sound<ms><special>Test (Python code)<ms>self.dtmfData=="3"<ms><special> <B><Shape>5<B>660<B>332<B> extra <special>Tool Tip<ms>play entering sound<ms><special>Test (Python code)<ms>self.dtmfData=="2"<ms><special> <B><Shape>5<B>507<B>312<B> extra <special>Tool Tip<ms>Test Roger voice<ms><special>Test (Python code)<ms>self.dtmfData=="1"<ms><special> <B><Shape>2<B>659<B>427<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>2<B>1058<B>385<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>5<B>581<B>341<B> extra <special>Tool Tip<ms>Repeat instructions<ms><special>Test (Python code)<ms>self.dtmfData=="4"<ms><special> <B><Shape>11<B>190<B>68<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>am<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestam<ms><special> <B><Shape>10<B>507<B>259<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "dtmf received of ", self.dtmfData<ms><special> <B><Shape>14<B>529<B>614<B> extra <special>Tool Tip<ms>Catch the timer which, when fired,
+indicates the end of this call<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>hanguptime<ms><special>Python variable to hold event data<ms>self.hanguptime<ms><special> <B><Shape>16<B>659<B>379<B> extra <special>Tool Tip<ms>play entering sound<ms><special>Filename to read audio from (Python code)<ms>"../prompts/entering.wav"<ms><special>answering machine node (Python code)<ms>self.amNode<ms><special> <B><Shape>9<B>291<B>382<B>291,386,334,382,332,395<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>2<B>769<B>426<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>14<B>251<B>461<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>DTMF<ms><special>Python variable to hold event data<ms>self.dtmfData<ms><special> <B><Shape>7<B>989<B>497<B> extra <special>Tool Tip<ms>End Call<ms><special>Worker node to activate (python code)<ms>self.amNode<ms><special> <B><Shape>10<B>282<B>279<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print " have a sound node of ", self.soundNode<ms><special> <B><Shape>12<B>990<B>549<B> extra <special>Tool Tip<ms>Initiate a timer, which causes this to
+end.<ms><special>Timer period (seconds)<ms>0.1<ms><special>Timer label (string literal)<ms>hanguptime<ms><special> <B><Shape>9<B>1039<B>386<B>1039,386,1082,387<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>248<B>182<B>248,183,308,182<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>214<B>304<B>214,304,262,356<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>16<B>770<B>378<B> extra <special>Tool Tip<ms>play leaving sound<ms><special>Filename to read audio from (Python code)<ms>"../prompts/leaving.wav"<ms><special>answering machine node (Python code)<ms>self.amNode<ms><special> <B><Shape>11<B>189<B>117<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>sound<ms><special>Timer period (seconds)<ms>2<ms><special>Timer label<ms>request sound<ms><special> <B><Shape>2<B>991<B>588<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>
Added: sofaswitch/trunk/callflow/tests/loadgraph.src
==============================================================================
--- (empty file)
+++ sofaswitch/trunk/callflow/tests/loadgraph.src Tue Oct 10 16:48:03 2006
@@ -0,0 +1 @@
+12<B>378<B>172<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds)<ms>2<ms><special>Timer label (string literal)<ms>endloadgraph<ms><special> <B><Shape>1<B>379<B>35<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>20<B>391<B>305<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>18<B>378<B>79<B> extra <special>Tool Tip<ms>Load New Graph<ms><special>new graph file (Python code)<ms>"am_test.graph"<ms><special> <B><Shape>10<B>378<B>126<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have generated the new graph"<ms><special> <B><Shape>14<B>389<B>221<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>endloadgraph<ms><special>Python variable to hold event data<ms>self.eventData<ms><special> <B><Shape>10<B>377<B>262<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "end the master now"<ms><special> <B><Shape>
Modified: sofaswitch/trunk/message.cxx
==============================================================================
--- sofaswitch/trunk/message.cxx (original)
+++ sofaswitch/trunk/message.cxx Tue Oct 10 16:48:03 2006
@@ -163,6 +163,11 @@
<tr><td> senddtmf </td><td> advise the recipient worker to send the folling dtmf stream to the remote voip node.
Typically, a voip worker would receive this message, and send dtmf to the
other end of the call. </td> </tr>
+<tr><td> receiveddtmf </td><td> A worker node has detected a DTMF sequence, and is passing the detected
+ sequence back to the controller. Typically, a voip worker would be able to
+ detect DTMF, and is passing this on to the controller. The sound node, and
+ telephone line handlers can also detect DTMF events (which are alternatively
+ key pad presses) </td> </tr>
<tr><td> requestnewid </td><td> A Supervisor will receive this message, create a new Worker, and reply with the
id of the created Worker.
An argument can be supplied. Currently, the only entity which uses this is the
Modified: sofaswitch/trunk/prompts/instructions.wav
==============================================================================
Binary files. No diff available.
Modified: sofaswitch/trunk/sofa/include/sofa/messages.h
==============================================================================
--- sofaswitch/trunk/sofa/include/sofa/messages.h (original)
+++ sofaswitch/trunk/sofa/include/sofa/messages.h Tue Oct 10 16:48:03 2006
@@ -81,6 +81,12 @@
/**A fifth flavour of sending a message */
void SendThisMessageTo(const char *message, const char * subj, PString dest);
+ /**have detected incoming DTMF from the remote world. This DTMF would be
+ detected by a voip worker node, or telephone line
+ handler. Consequently, a message has to be sent to the remote controller
+ advising them of the received DTMF */
+ void DtmfReceivedFromTheWorld(const PString & receivedDtmf);
+
/**Report the name of the node that last sent us a message */
PString GetLastSender() { return lastSender; }
Modified: sofaswitch/trunk/sofa/src/messages.cxx
==============================================================================
--- sofaswitch/trunk/sofa/src/messages.cxx (original)
+++ sofaswitch/trunk/sofa/src/messages.cxx Tue Oct 10 16:48:03 2006
@@ -136,6 +136,11 @@
PTRACE(3, "DEstructor for MessageFrame " << ourId);
}
+void MessageFrame::DtmfReceivedFromTheWorld(const PString & receivedDtmf)
+{
+ SendThisMessageTo(PString("RECEIVEDDTMF ") + receivedDtmf, GetRemoteController());
+}
+
void MessageFrame::CloseMessagesSocket()
{
PTRACE(3, "Close messages socket for " << GetOurId());
1
0
09 Oct '06
Author: derek
Date: Mon Oct 9 17:56:31 2006
New Revision: 147
Modified:
sofaswitch/trunk/callflow/tests/dtmf_from_sound.src
sofaswitch/trunk/callflow/tests/forloop.src
sofaswitch/trunk/callflow/tests/requestnode.src
sofaswitch/trunk/callflow/tests/simpleeventer.src
sofaswitch/trunk/callflow/tests/simplesimple.src
sofaswitch/trunk/callflow/tests/timetest.src
Log:
Update these files with new icons.
Modified: sofaswitch/trunk/callflow/tests/dtmf_from_sound.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/dtmf_from_sound.src (original)
+++ sofaswitch/trunk/callflow/tests/dtmf_from_sound.src Mon Oct 9 17:56:31 2006
@@ -1 +1 @@
-10<B>108<B>407<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "DTMF detected is ", self.dtmfData<ms><special> <B><Shape>9<B>295<B>275<B>295,275,348,279<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>130<B>361<B>258,390,131,361,130,363<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>14<B>120<B>365<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>DTMF<ms><special>Python variable to hold event data<ms>self.dtmfData<ms><special> <B><Shape>14<B>246<B>251<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>REQ<ms><special>Python variable to hold event data<ms>self.newNode<ms><special> <B><Shape>9<B>135<B>374<B>349,374,345,440,135,455<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>323<B>322<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "timer has expired at ", time.asctime(), " ", self.timerData<ms><special> <B><Shape>1<B>231<B>108<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>2<B>107<B>453<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>10<B>232<B>204<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "Have requested a node from sound at ", time.asctime()<ms><special> <B><Shape>14<B>334<B>283<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>requestnode<ms><special>Python variable to hold event data<ms>self.timerData<ms><special> <B><Shape>10<B>231<B>295<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have a new node on ", self.newNode<ms><special> <B><Shape>13<B>231<B>340<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>requestnode<ms><special> <B><Shape>11<B>232<B>159<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>sound<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestnode<ms><special> <B><Shape>
+2<B>320<B>493<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>5<B>108<B>450<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>self.dtmfData=="*"<ms><special> <B><Shape>10<B>108<B>407<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "DTMF detected is ", self.dtmfData<ms><special> <B><Shape>20<B>120<B>491<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>9<B>130<B>361<B>258,390,131,361,130,363<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>14<B>246<B>251<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>REQ<ms><special>Python variable to hold event data<ms>self.newNode<ms><special> <B><Shape>11<B>232<B>159<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>sound<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestnode<ms><special> <B><Shape>14<B>334<B>283<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>requestnode<ms><special>Python variable to hold event data<ms>self.timerData<ms><special> <B><Shape>1<B>231<B>108<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>9<B>157<B>475<B>157,475,347,493<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>13<B>231<B>340<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>requestnode<ms><special> <B><Shape>9<B>345<B>370<B>348,370,345,494<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>323<B>322<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "timer has expired at ", time.asctime(), " ", self.timerData<ms><special> <B><Shape>10<B>231<B>295<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have a new node on ", self.newNode<ms><special> <B><Shape>9<B>295<B>275<B>295,275,348,279<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>14<B>120<B>365<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>DTMF<ms><special>Python variable to hold event data<ms>self.dtmfData<ms><special> <B><Shape>10<B>232<B>204<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "Have requested a node from sound at ", time.asctime()<ms><special> <B><Shape>
Modified: sofaswitch/trunk/callflow/tests/forloop.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/forloop.src (original)
+++ sofaswitch/trunk/callflow/tests/forloop.src Mon Oct 9 17:56:31 2006
@@ -1 +1 @@
-9<B>258<B>84<B>296,87,258,84,259,174,299,178<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>1<B>306<B>11<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>3<B>299<B>62<B> extra <special>Tool Tip<ms>Start For<ms><special>Initialise (Python code)<ms>self.i = 0<ms><special>Test for Termination (Python code)<ms>self.i < 10<ms><special>Increment (Python code)<ms>self.i+=1<ms><special> <B><Shape>10<B>307<B>108<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "loop index is ", self.i<ms><special> <B><Shape>4<B>301<B>152<B> extra <special>Tool Tip<ms>End For Loop<ms><special> <B><Shape>20<B>308<B>200<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>
+10<B>307<B>108<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "loop index is ", self.i<ms><special> <B><Shape>3<B>299<B>62<B> extra <special>Tool Tip<ms>Start For<ms><special>Initialise (Python code)<ms>self.i = 0<ms><special>Test for Termination (Python code)<ms>self.i < 10<ms><special>Increment (Python code)<ms>self.i+=1<ms><special> <B><Shape>1<B>306<B>11<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>20<B>322<B>199<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>4<B>301<B>152<B> extra <special>Tool Tip<ms>End For Loop<ms><special> <B><Shape>9<B>258<B>84<B>296,87,258,84,259,174,299,178<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>
Modified: sofaswitch/trunk/callflow/tests/requestnode.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/requestnode.src (original)
+++ sofaswitch/trunk/callflow/tests/requestnode.src Mon Oct 9 17:56:31 2006
@@ -1 +1 @@
-2<B>231<B>391<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>10<B>323<B>322<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "timer has expired at ", time.asctime(), " from ", self.timerData<ms><special> <B><Shape>9<B>259<B>371<B>347,371,259,391<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>14<B>244<B>255<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>NEWID<ms><special>Python variable to hold event data<ms>self.eventData<ms><special> <B><Shape>14<B>336<B>282<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>requestnode<ms><special>Python variable to hold event data<ms>self.timerData<ms><special> <B><Shape>13<B>231<B>340<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>requestnode<ms><special> <B><Shape>9<B>290<B>279<B>290,280,350,279<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>231<B>295<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have a new node on ", self.eventData<ms><special> <B><Shape>1<B>231<B>157<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>11<B>231<B>208<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>voip<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestnode<ms><special> <B><Shape>
+14<B>336<B>282<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>requestnode<ms><special>Python variable to hold event data<ms>self.timerData<ms><special> <B><Shape>1<B>231<B>157<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>2<B>323<B>370<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>13<B>231<B>340<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>requestnode<ms><special> <B><Shape>10<B>231<B>295<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have a new node on ", self.eventData<ms><special> <B><Shape>20<B>245<B>386<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>11<B>231<B>208<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>voip<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestnode<ms><special> <B><Shape>14<B>244<B>255<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>NEWID<ms><special>Python variable to hold event data<ms>self.eventData<ms><special> <B><Shape>9<B>290<B>279<B>290,280,350,279<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>323<B>322<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "timer has expired at ", time.asctime(), " from ", self.timerData<ms><special> <B><Shape>
Modified: sofaswitch/trunk/callflow/tests/simpleeventer.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/simpleeventer.src (original)
+++ sofaswitch/trunk/callflow/tests/simpleeventer.src Mon Oct 9 17:56:31 2006
@@ -1 +1 @@
-9<B>349<B>148<B>349,148,351,201<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>2<B>327<B>251<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>1<B>285<B>27<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>14<B>301<B>125<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>REQ<ms><special>Python variable to hold event data<ms>self.newNode<ms><special> <B><Shape>10<B>287<B>172<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have received a new node ", self.newNode<ms><special> <B><Shape>10<B>326<B>202<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print " Finished main stream of execution "<ms><special> <B><Shape>9<B>315<B>219<B>315,219,315,250,349,253<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>11<B>286<B>78<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>voip<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestnode<ms><special> <B><Shape>
+10<B>287<B>172<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "have received a new node ", self.newNode<ms><special> <B><Shape>20<B>300<B>324<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>2<B>327<B>251<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>10<B>326<B>202<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print " Finished main stream of execution "<ms><special> <B><Shape>9<B>349<B>148<B>349,148,351,201<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>1<B>285<B>27<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>11<B>286<B>78<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>voip<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>requestnode<ms><special> <B><Shape>14<B>301<B>125<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>REQ<ms><special>Python variable to hold event data<ms>self.newNode<ms><special> <B><Shape>9<B>312<B>219<B>312,219,312,326<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>
Modified: sofaswitch/trunk/callflow/tests/simplesimple.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/simplesimple.src (original)
+++ sofaswitch/trunk/callflow/tests/simplesimple.src Mon Oct 9 17:56:31 2006
@@ -1 +1 @@
-20<B>333<B>121<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>1<B>332<B>75<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>
+1<B>376<B>108<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>20<B>389<B>149<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>
Modified: sofaswitch/trunk/callflow/tests/timetest.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/timetest.src (original)
+++ sofaswitch/trunk/callflow/tests/timetest.src Mon Oct 9 17:56:31 2006
@@ -1 +1 @@
-10<B>207<B>305<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "t2 ", time.asctime(), " data is ", self.timer2<ms><special> <B><Shape>14<B>139<B>179<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>timer1<ms><special>Python variable to hold event data<ms>self.timer1Data<ms><special> <B><Shape>9<B>270<B>278<B>270,280,359,278<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>188<B>201<B>188,201,231,202<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>14<B>220<B>256<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>timer2<ms><special>Python variable to hold event data<ms>self.timer2<ms><special> <B><Shape>14<B>347<B>327<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>10<ms><special>Python variable to hold event data<ms>self.timer3<ms><special> <B><Shape>10<B>126<B>221<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "t1 ", time.asctime(), " data is ", self.timer1Data<ms><special> <B><Shape>12<B>127<B>125<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>timer1<ms><special> <B><Shape>9<B>150<B>271<B>150,271,152,406,223,407,229,423<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>12<B>335<B>275<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds)<ms>10<ms><special>Timer label (string literal)<ms>t10<ms><special> <B><Shape>9<B>228<B>419<B>228,423,358,419<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>1<B>123<B>26<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>10<B>334<B>370<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "t10 ", time.asctime(), " data is ", self.timer3<ms><special> <B><Shape>10<B>123<B>74<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "Start ", time.asctime()<ms><special> <B><Shape>12<B>207<B>202<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds)<ms>2<ms><special>Timer label<ms>timer2<ms><special> <B><Shape>2<B>204<B>423<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>9<B>231<B>351<B>232,351,231,422<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>
+14<B>220<B>256<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>timer2<ms><special>Python variable to hold event data<ms>self.timer2<ms><special> <B><Shape>14<B>347<B>327<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>10<ms><special>Python variable to hold event data<ms>self.timer3<ms><special> <B><Shape>20<B>346<B>417<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>12<B>127<B>125<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>timer1<ms><special> <B><Shape>10<B>123<B>74<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "Start ", time.asctime()<ms><special> <B><Shape>10<B>334<B>370<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "t10 ", time.asctime(), " data is ", self.timer3<ms><special> <B><Shape>10<B>126<B>221<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "t1 ", time.asctime(), " data is ", self.timer1Data<ms><special> <B><Shape>12<B>207<B>202<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds)<ms>2<ms><special>Timer label<ms>timer2<ms><special> <B><Shape>10<B>207<B>305<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "t2 ", time.asctime(), " data is ", self.timer2<ms><special> <B><Shape>9<B>270<B>278<B>270,280,359,278<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>12<B>335<B>275<B> extra <special>Tool Tip<ms>Timer<ms><special>Timer period (seconds)<ms>10<ms><special>Timer label (string literal)<ms>t10<ms><special> <B><Shape>9<B>231<B>351<B>232,351,231,422<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>2<B>204<B>419<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>1<B>123<B>26<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>14<B>139<B>179<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>timer1<ms><special>Python variable to hold event data<ms>self.timer1Data<ms><special> <B><Shape>9<B>150<B>271<B>150,271,152,406,223,407,229,423<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>188<B>201<B>188,201,231,202<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>
1
0
09 Oct '06
Author: derek
Date: Mon Oct 9 17:55:32 2006
New Revision: 146
Modified:
sofaswitch/trunk/callflow/tests/makevoipcall.src
Log:
Update this file.
Modified: sofaswitch/trunk/callflow/tests/makevoipcall.src
==============================================================================
--- sofaswitch/trunk/callflow/tests/makevoipcall.src (original)
+++ sofaswitch/trunk/callflow/tests/makevoipcall.src Mon Oct 9 17:55:32 2006
@@ -1 +1,3 @@
-10<B>128<B>491<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>self.i = 0<ms><special> <B><Shape>9<B>291<B>382<B>291,386,334,382,332,395<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>150<B>467<B>265,596,208,591,205,467,150,478,154,493<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>13<B>284<B>231<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>request sound<ms><special> <B><Shape>9<B>248<B>182<B>248,183,308,182<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>1<B>190<B>19<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>10<B>239<B>508<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "dtmf received of ", self.dtmfData<ms><special> <B><Shape>14<B>251<B>463<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>DTMF<ms><special>Python variable to hold event data<ms>self.dtmfData<ms><special> <B><Shape>2<B>266<B>623<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>9<B>217<B>357<B>217,357,265,359<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>11<B>189<B>117<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>sound<ms><special>Timer period (seconds)<ms>2<ms><special>Timer label<ms>request sound<ms><special> <B><Shape>15<B>129<B>540<B> extra <special>Tool Tip<ms>Transfer Media<ms><special>First SofaSwitch worker (python)<ms>"sound"<ms><special>Second SofaSwitch worker (python)<ms>"sound"<ms><special> <B><Shape>13<B>190<B>260<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>request voip<ms><special> <B><Shape>5<B>240<B>549<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>self.dtmfData=="9"<ms><special> <B><Shape>14<B>202<B>162<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>voipREQ<ms><special>Python variable to hold event data<ms>self.voipNode<ms><special> <B><Shape>14<B>295<B>185<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>soundREQU<ms><special>Python variable to hold event data<ms>self.soundNode<ms><special> <B><Shape>10<B>282<B>279<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print " have a sound node of ", self.soundNode<ms><special> <B><Shape>6<B>191<B>209<B> extra <special>Tool Tip<ms>Make Call<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special>Call destination (python code)<ms>"h323:h323.voxgratia.org"<ms><special> <B><Shape>2<B>307<B>394<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>5<B>241<B>359<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>(self.voipNode != None) and (self.soundNode != None)<ms><special> <B><Shape>15<B>240<B>412<B> extra <special>Tool Tip<ms>Transfer Media<ms><special>First SofaSwitch worker (python)<ms>self.voipNode<ms><special>Second SofaSwitch worker (python)<ms>self.soundNode<ms><special> <B><Shape>10<B>190<B>308<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "Have a new voip node on ", self.voipNode<ms><special> <B><Shape>11<B>190<B>68<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>voip<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>request voip<ms><special> <B><Shape>20<B>127<B>632<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>9<B>266<B>329<B>308,329,266,359<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>19<B>267<B>578<B> extra <special>Tool Tip<ms>Send Dtmf<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special>DTMF to send to worker node (python code)<ms>self.dtmfData<ms><special> <B><Shape>7<B>129<B>587<B> extra <special>Tool Tip<ms>End Call<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special> <B><Shape>
+9<B>248<B>182<B>248,183,308,182<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>2<B>44<B>394<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>12<B>43<B>349<B> extra <special>Tool Tip<ms>Initiate a timer, which causes this to
+end.<ms><special>Timer period (seconds)<ms>0.1<ms><special>Timer label (string literal)<ms>hanguptime<ms><special> <B><Shape>7<B>42<B>303<B> extra <special>Tool Tip<ms>End Call<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special> <B><Shape>2<B>307<B>394<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>13<B>284<B>231<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>request sound<ms><special> <B><Shape>1<B>190<B>19<B> extra <special>Tool Tip<ms>Start Processing<ms><special> <B><Shape>15<B>42<B>257<B> extra <special>Tool Tip<ms>Transfer Media<ms><special>First SofaSwitch worker (python)<ms>"sound"<ms><special>Second SofaSwitch worker (python)<ms>"sound"<ms><special> <B><Shape>5<B>241<B>359<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>(self.voipNode != None) and (self.soundNode != None)<ms><special> <B><Shape>11<B>189<B>117<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>sound<ms><special>Timer period (seconds)<ms>2<ms><special>Timer label<ms>request sound<ms><special> <B><Shape>10<B>239<B>508<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "dtmf received of ", self.dtmfData<ms><special> <B><Shape>11<B>190<B>68<B> extra <special>Tool Tip<ms>Request Node<ms><special>Request node from<ms>voip<ms><special>Timer period (seconds)<ms>1<ms><special>Timer label<ms>request voip<ms><special> <B><Shape>13<B>190<B>260<B> extra <special>Tool Tip<ms>Stop Timer<ms><special>Timer to stop<ms>request voip<ms><special> <B><Shape>9<B>266<B>329<B>308,329,266,359<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>6<B>191<B>209<B> extra <special>Tool Tip<ms>Make Call<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special>Call destination (python code)<ms>"h323:h323.voxgratia.org"<ms><special> <B><Shape>9<B>217<B>357<B>217,357,265,359<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>9<B>291<B>382<B>291,386,334,382,332,395<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>43<B>211<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "hangup, as dtmf 9 has been received"<ms><special> <B><Shape>20<B>368<B>626<B> extra <special>Tool Tip<ms>Death<ms><special> <B><Shape>9<B>302<B>486<B>302,486,376,486,380,579<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>5<B>240<B>549<B> extra <special>Tool Tip<ms>Conditional<ms><special>Test (Python code)<ms>self.dtmfData=="9"<ms><special> <B><Shape>15<B>240<B>412<B> extra <special>Tool Tip<ms>Transfer Media<ms><special>First SofaSwitch worker (python)<ms>self.voipNode<ms><special>Second SofaSwitch worker (python)<ms>self.soundNode<ms><special> <B><Shape>14<B>295<B>185<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>soundREQU<ms><special>Python variable to hold event data<ms>self.soundNode<ms><special> <B><Shape>14<B>202<B>162<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>voipREQ<ms><special>Python variable to hold event data<ms>self.voipNode<ms><special> <B><Shape>2<B>266<B>623<B> extra <special>Tool Tip<ms>End Processing<ms><special> <B><Shape>9<B>63<B>173<B>262,598,139,599,141,173,63,174,67,213<special>Tool Tip<ms>Join blocks shape<ms><special> <B><Shape>10<B>190<B>308<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print "Have a new voip node on ", self.voipNode<ms><special> <B><Shape>14<B>367<B>581<B> extra <special>Tool Tip<ms>Catch the timer which, when fired,
+indicates the end of this call<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>hanguptime<ms><special>Python variable to hold event data<ms>self.hanguptime<ms><special> <B><Shape>19<B>267<B>578<B> extra <special>Tool Tip<ms>Send Dtmf<ms><special>Worker node to activate (python code)<ms>self.voipNode<ms><special>DTMF to send to worker node (python code)<ms>self.dtmfData<ms><special> <B><Shape>10<B>282<B>279<B> extra <special>Tool Tip<ms>Python<ms><special>Python Code<ms>print " have a sound node of ", self.soundNode<ms><special> <B><Shape>14<B>251<B>463<B> extra <special>Tool Tip<ms>Eventer<ms><special>Event sought (Python code)<ms><ms><special>Event sought (Regular Exp)<ms>DTMF<ms><special>Python variable to hold event data<ms>self.dtmfData<ms><special> <B><Shape>
1
0