These generate random strings so it is difficult to unit test. But
the invocation worked:
st> Osmo.SIPRandomHelper generateTag
'MzU0MjIxMTQ1OTIzODI1ODc3NjU_'
st> Osmo.SIPRandomHelper generateCallId
'MTk3MTU3OTAxOA__@xiaoyu'
st> Osmo.SIPUserAgent generateBranch
'z9hG4bKMzU0MjIwNDM2Myw0MjIxNg__'
* Change the category for the tests and extensions
* Rewrite usages of >>nl and >>cr
* There are still issues with the Socket code, Datagram handling
and and expands.
Use DatagramSocket>>ensureReadable as this is using async poll,
make sure the socket is still open after ensureReadable returns.
Move the RX/TX into selectors as this allows us to return from
them.
The class was called SIPSecureRandom as it used /dev/random for
random numbers. The downside of /dev/random is that a read can
block until enough data has been generated. This does occur, e.g.
on an isolated system. Start using /dev/urandom for the tags. It
is better than the Mersene twister of GST but it is no source
for key material.
* This isn't doing proper routing (e.g. the via is not modified
properly but we return it to the right address)
* An unknown BYE will be acked with a 481. The 'respondWith:...'
includes the wrong 'Allow:' but it is good enough from the
structure for now.
* Re-Order the loading of files as the SIPUserAgent is extended
the SIPRequests.
* Add the port/ip to the SIPDialog so that responding to the
request is possible.
The name session base is a bit misleading as it is not the session
that holds the initial dialog, the confirmed dialog, the UAS and then
also the session when it is setup. When the dialog gets confirmed we
will register it with the useragent and then will be called for new
requests. On hangup/cancel the dialog will be scheduled for removal.
Constructing a PetitParser is an expensive operation (Object>>becomeForward:)
we can keep the parser in the class. For the SIPTransactions we keep it as
a global, it is assumed that all SIPTransactions operate through the same
process and will not run into concurrency issues.
This is still more complicated (and wrong) then it should be,
when we CANCEL an INVITE we can either send a CANCEL or we need
to wait for a 100. Now the CANCEL could be too late (the server
already sent a 200), in that case we would get a 200 for the
INVITE and pass this to the higher levels (which we probably
should).
The code only tests this with the response but it should work for
the request as well. Depending on this one needs to switch from/to
but this needs to happen on a higher level.
The CSeq only needs to be unique within a dialog, so we can have
a global function to generate a valid CSeq start (< 2^31) and then
handle cseq's within the dialog.
Introduce a high level class that can create multiple transactions,
handles the sequence numbers, the dialogs, the opened session and
provides a nice call, hangup, cancel, terminate interface.
This is fixing a previous commit, fixes the timed out handling, attempts
to change the initial dialog -> confirmed dialog handling (but still
gets it wrong, it should compare the dialog, or just get a new dialog
from the response and check if it is compatible with the initial dialog).
Only the INVITE transaction can be canceled, when it gets
canceled we might or might not get a confirmation or we might
be too late to cancel things. With this flag we will be able
to do something sensible when we get a late final response.
The transaction now work on something called an initial dialog, e.g.
during a INVITE we go from an initial dialog to a confirmed dialog and
maybe create a session. Prepare the code to support this.
It is still not clear how callbacks, dialog confirmation and session
creation will be handled but it will somehow fit together.
Parse every generic_param (or specialized) into a SIPGenericParam,
provide a asFoldedString implementation, tell the folding code about
it, create a SIPToFromParam that holds the list of params.
Dispatch the data from thre socket in a new context. This assures
that we will not run into locking issues. One day where we will have
VMs that can use multiple cores we might have a dispatcher set in
each transaction/session. The we could establish a rule that each
transaction is dispatched in the right/same queue.