FAQ

From reSIProcate
(Redirected from Faq)
Jump to: navigation, search

Nothing is happening, what's wrong?[edit]

You must add transports.

All I'm receiving is 503s, why?[edit]

You must add transports.

How do I convert from a NameAddr or a URI to a data?[edit]

You can use Data::from() on any class or object that supports operator << on std::ostream. For example:

NameAdder foo;
Data d=Data::from(foo);

Why does addTransport throw?[edit]

addTransport throws if the transport could not be created/connected. One reason the transport could fail is that the port is already in use.

Can I remove transports?[edit]

No.

There are some assumptions much of the stack makes about transports that makes removing them at runtime currently infeasible (if you were to hack the code and do the simplest thing most of us have tried, you would be surprised by some spectacular crashes). We have some ideas about making changes that will make this possible in the future.

Why does dynamic_cast<MyContents*>(foo) return 0?[edit]

There are three reason you may get a zero from this cast:

  1. there is no body
  2. there is a body, but it is of a different MIME type than specified in the cast
  3. there is a body of the desired MIME type but the derived content type was not #included

You have to include the contents header file in the file that has the main library (for example, #include “SdpContents.hxx”) otherwise dynamic casts will fail. There will be a body, but it will have the default type.

How does the buildFdSet, select, process loop work?[edit]

These series of function calls are required in order to allow the stack to run entirely in a single thread.

  1. buildFdSet() - iterates through the transports and other components (ie. DNS resolver) and adds file descriptors to a File Descriptor set or FdSet.
  2. select() - the file descriptors in the FdSet all default to a signaled state when added by the buildFdSet method. Calling select will cause the file descriptors to flip to the unsignaled state and the running thread to block until one of the file descriptors is signaled. Usually this means there is new data on the wire (ie. a SIP message or DNS result) or a socket is ready to be written to. When select completes the FdSet will be modified and those file descriptors that are ready are set to the signaled state. If a timeout occurs, then no file descriptors in the set will be signaled.
  3. process() - a selected FdSet must be provided. This call gives the stack cycles to run. The stack will iterate through the transports and other components giving them cycles to do work. This work includes processes such as: reading a message from the wire (SIP Message or DNS result), writting a message to the wire or processing a timeout. Warning: It is important to ensure that the FdSet you pass in has been generated by a call to buildFdSet and that is has been used in a select call - if you fail to call select then the process call will think all file descriptors passed in are signaled, and this can cause unpredicable behaviour.

I told the stack to send a provisional response to a REGISTER and nothing happened. What happened?[edit]

The stack not only thinks that's a bad idea, it corrects your behavior by dropping the response.

Are there any quirks about TCP behavior I should know about?[edit]

If the stack acts as a UAS for a request received over TCP and the other side closes the connection before we respond, we will try to connect to other destination of that tuple, but if that fails, we won't open a new connection to send a response. No errors will be returned to the application.

How can I tell if I have multiple values for a single-value header field?[edit]

if (msg->getRawHeader(h_To)->size() != 1)
{
   ...
}

If the size() call doesn't equal one, you have more than one value for the To header field.


In DUM I use AppDialogSet->end() to cancel a Client Invite Session, but it doesn't work?[edit]

It is most likely because when you created the INVITE message - you made a copy of it, then called dum->send(). It is very important not to copy the message, but to pass the same SipMessage (by reference) you get back from the makeXXXX functions to the send function.

Essentially the send() function changes the branch parameter, right before it sends - and if you pass a copy of the message, then the message stored in DUM will not have it's branch parameter updated - thus when you call CANCEL, it uses the wrong branch parameter.

Bad Example:

SipMessage invite = dum->makeInviteSession(...);
dum->send(invite);

Good Example:

SipMessage &invite = dum->makeInviteSession(...);
dum->send(invite);