Re: [reSIProcate] process incoming calls design question - UML seqdiagram attached
I'll take a crack at this... I'm not part of the Resip development team
but I've been working with the code for quite a while, learned a lot of
hard lessons and am doing some of the same work you are describing.
What I say may not be part of the design goals but it is what I have
found to work.
If you guys take another crack at relationships
AppDialog/AppDialogSet/Dialogs/etc please post an invitation for
comments. While I like most of what was done some things could be easier
and I have some requests! The biggest thing I want to do is divorce the
Stack/DUM/Dialogs from the Application side but some of the knowledge
needed on the application side is too embedded right now.
The basics of what I am doing (and understand that you are trying to do):
- Resip/Stack/DUM all run within a thread
- The "application" runs asynchronously in other thread(s)
- "events" are generated from DUM callbacks for the "application" to
deal with later
- The application makes DUM requests as it sees fit during a "call"
lifecycle.
- We're only talking about INVITE sessions here - no
Publish/Subscribe/NIS stuff (I haven't dove into that yet).
1) You need a "forward" reference from DUM to your application data. I
build a string from DialogId() (is->getAppDialog()->getDialogId()) and
store it in a map with a refrence to my object.
2) The "reverse" reference for your application must be the
InviteSessionHandle (it casts so Client/Server) in order to get requests
back to DUM. I found no other option.
These 2 issues make it a "loose" coupling between DUM and the
application. My biggest issue with DUM right now and storing info in
AppDialog/AppDialogSet is it goes away at a very wrong time for me - DUM
may be done with it but my application wasn't. Making this "loose"
creates another issue - either the application or the DUM could make
objects go away at really bad times. I handled this with locks. I
haven't had a need to use an AppDialog for anything - an AppDialogSet is
mandatory to "marry" up an outbound invite because it is the only way to
get the DialogSetId() back.
3) The Resip/DUM processing runs as its own thread but NOT the thread
dum::process() they have defined. There must be a mutex that is owned
by the Resip thread when dum::process(fdset) is executing or by an
application thread when it is referencing an InviteSession handle.
Watch the case of DUM executing a callback that your application
immediately calls into DUM to respond - deadlock if not handled correctly.
4) ALWAYS (after aquiring the lock) to an invitesessionhandle.isValid()
to make sure DUM hasn't destroyed the object - if it is valid it will
stay valid through the duration of the lock (if you get locking right).
5) ALWAYS send() messages that relate to a session via
invitesessionhandle->send() and NOT dum->send(). The send() on session
handles is overloaded to special-case state handling based on current
state and response. Failure to do this creates strange problems in state
transitions in dialogs.
6) WATCH OUT for recurisve loops (this is how I also found #5).
OnNewSession() calling app code calling send(reject()) results in DUM
(within the context of OnNewSession!!!) calling onTerminated() calling
application code. It got deeper than I expected and posed problems with
locking/events. Example:
dum->process()
handler->onNewSession(server)
application->handleNewSession()
is->send(is->reject(486))
handler->onTerminated()
application->handleTerminated()
At that point my MyAppDialog() instance went away with me 2 levels deep
in calls... just a lesson.
7) I have not found ANY circumstances where you MUST call send() or
provide information in the context of the executing callback -
everything I have tried has worked fine from delayed application
handling as long as I used the invitesession->send(). DEVELOPERS: Can
you confirm this??
8) The way DUM implements Handled:: is MUCH cleaner than what I am doing
and I didn't understand it initially so I avoided it. Now I'm going to
review my code an do something similar with 2 additions:
- the ability to lock() a handle so the object can't be destroyed yet
to pacify some of the interlock issues by scoping a lock to a call
instance instead of the entire DUM execution or application execution.
- an external "reference" so I don't have to keep the handle. In this
case DialogId as a string.
I have code doing this at the moment dealing with the multiple threads,
handling events, handling inbound calls and basic handling in place for
outbound calls. By no means is it an application at this time. The goal
of this is a "Media Server Application Framework" that supports SIP/MGCP
on one side and Media Servers (small imbedded, Snowshore for basic,
conference, VXML, Convedia if I can get my hands on one) via an
abstracted interface that can be event based or a per-thread procedural
method which makes building quick applications very easy.
The goal is open source but non-GPL non-Commercial use at this time...
that said, if anybody wants it to take a look at how some things are
structure just drop me a line (Linux 2.6 w/NPTL and TLS, autoconf -
probably won't run on windows today). Remember - it is ROUGH at this
time and I'm proving out some interfaces but the interlocking is there.
Jay
Scott Godin wrote:
You may want to have a look at the AppDialog and AppDialogSet objects. A
quick sample of their use is in BasicCall.cxx. You can override with your
own derived class and store pointers to these objects in your app.
-----Original Message-----
From: resiprocate-devel-bounces@xxxxxxxxxxxxxxxxxxx
[mailto:resiprocate-devel-bounces@xxxxxxxxxxxxxxxxxxx] On Behalf Of Justin
Matthews
Sent: Saturday, January 22, 2005 3:10 PM
To: resiprocate-devel@xxxxxxxxxxxxxxxxxxx
Subject: [reSIProcate] process incoming calls design question - UML
seqdiagram attached
Hello,
I have a question on how to use the dum. After handling the callbacks with
my InviteSessionHandler derived class, I would like to store a minimal
amount of information so that I can get the appropriate InviteSession for a
call at a later time. For example, when onNewSession is called I need to
asynchronously pass the information about the new call to my apps internal
system which will eventually call InviteSession::provisional and then
InviteSession::send. How would my internal system get the appropriate
InviteSession? What is the best way to do this? Simply store the
ServerInviteSessionHandle passed into my InviteSessionHandler? Ideally I
would not like to keep track of dum data objects such as the handle. Is
there a way to get a reference to the correct InviteSessionHandle using
parts of the message (callid, to, from)?
Also, I will be doing at least a few more UML diagrams such as the one
attached. Please let me know if it is incorrect. Being a newbie to the
system I find this is the best way for me to jump on the learning curve.
Are similar docs being developed right now for the dum? I am willing to
continue to post my docs to this thread and/or be educated on the current
documentation plan to help in generating similar docs for the project.
Thanks,
-Justin
_______________________________________________
resiprocate-devel mailing list
resiprocate-devel@xxxxxxxxxxxxxxxxxxx
https://list.sipfoundry.org/mailman/listinfo/resiprocate-devel