The upper layer registrations are callbacks that the stack invokes to deliver processed inbound SIP messages. The stack also invokes the upper layer registrations when certain events occur. The structure is given by the following code:
void (*sip_ulp_recv)(const sip_conn_object_t, sip_msg_t, const sip_dialog_t);
This code is a routine that the application must register for the stack to deliver inbound SIP message after processing. The SIP stack invokes this function with the connection object on which the message arrived the SIP message, and associated dialog, if any. The SIP message will be freed once this function returns. If the application wishes to use the message beyond that, it has to hold a reference to the message by using the sip_hold_msg() and release it by using the sip_free_msg() function after use. Similarly, if the application wishes to cache the dialog, it must increment the reference to the dialog by using the sip_hold_dialog() and release it by using the sip_release_dialog() function after use.
uint_t (*sip_ulp_timeout)(void *, void (*func)(void *), struct timeval *); boolean_t (*sip_ulp_untimeout)(uint_t);
An application can register these two routines if it wants to implement its own timer routines for the stack timers. Typically, an application may not provide these and let the stack use its own built-in timer routines. The timer routines implemented by the stack are only for use by the stack. These routines are not available to applications. If the application registers one, then it must also register the other.
int (*sip_ulp_trans_error)(sip_transaction_t, int, void *);
The application can register this routine if it wants to be notified of a transaction error. Typically this error occurs when the transaction layer tries to send a message (could be a retransmission or responding to a retransmitted request or sending an ACK request for a non-2xx final response) using a cached connection object which fails. If this routine is not registered, on such a failure, the transaction is terminated. The final argument is for future use, it is always set to NULL.
void (*sip_ulp_dlg_del)(sip_dialog_t, sip_msg_t, void *);
An application can register this routine if it wants to be notified when a dialog is deleted. The dialog that is going to be deleted is passed along with the SIP message, that caused the dialog to be deleted. The final argument is for future use and is always set to NULL.
void (*sip_ulp_trans_state_cb)(sip_transaction_t, sip_msg_t, int, int); void (*sip_ulp_dlg_state_cb)(sip_dialog_t, sip_msg_t, int, int);
These two callback routines, if registered, are invoked by the stack when a transaction (sip_ulp_trans_state_cb) or a dialog (sip_ulp_dlg_state_cb) changes states. The message causing the transition is passed along with the transaction/dialog and also the old (before transition) and current (after transition) states.