call osip_init to init the osip library
create transport layer to handle the outgoing and incoming messages.
It implements transaction layer which is defined by RFC3261
osip structure
struct osip
{
/* list of transactions for ict, ist, nict, nist */
osip_list_t *osip_ict_transactions; /**< list of ict transactions */
osip_list_t *osip_ist_transactions; /**< list of ist transactions */
osip_list_t *osip_nict_transactions; /**< list of nict transactions */
osip_list_t *osip_nist_transactions; /**< list of nist transactions */
osip_list_t *ixt_retransmissions; /**< list of ixt elements */
osip_message_cb_t msg_callbacks[OSIP_MESSAGE_CALLBACK_COUNT];
osip_kill_transaction_cb_t kill_callbacks[OSIP_KILL_CALLBACK_COUNT];
osip_transport_error_cb_t
tp_error_callbacks[OSIP_TRANSPORT_ERROR_CALLBACK_COUNT];
int (*cb_send_message) (osip_transaction_t *, osip_message_t *, char *,
int, int);
};
Transaction type:
ICT, /**< Invite Client (outgoing) Transaction */
IST, /**< Invite Server (incoming) Transaction */
NICT,/**< Non-Invite Client (outgoing) Transaction */
NIST /**< Non-Invite Server (incoming) Transaction */
Events:
RCV_REQINVITE, /**< Event is an incoming INVITE request */
RCV_REQACK, /**< Event is an incoming ACK request */
RCV_REQUEST, /**< Event is an incoming NON-INVITE and NON-ACK request */
RCV_STATUS_1XX, /**< Event is an incoming informational response */
RCV_STATUS_2XX, /**< Event is an incoming 2XX response */
RCV_STATUS_3456XX,/**< Event is an incoming final response (not 2XX) */
/* FOR OUTGOING MESSAGE */
SND_REQINVITE, /**< Event is an outgoing INVITE request */
SND_REQACK, /**< Event is an outgoing ACK request */
SND_REQUEST, /**< Event is an outgoing NON-INVITE and NON-ACK request */
SND_STATUS_1XX, /**< Event is an outgoing informational response */
SND_STATUS_2XX, /**< Event is an outgoing 2XX response */
SND_STATUS_3456XX,/**< Event is an outgoing final response (not 2XX) */
KILL_TRANSACTION, /**< Event to 'kill' the transaction before termination */
/* other timer event not listed here*/
Callback:
There are four kinds of callbacks upper layer need to set for osip library:
osip_message_cb_t msg_callbacks[OSIP_MESSAGE_CALLBACK_COUNT];
Osip lib will call message callbacks to notify upper layer some information
osip_kill_transaction_cb_t kill_callbacks[OSIP_KILL_CALLBACK_COUNT];
Osip lib will call these callbacks when a transaction is finished.
osip_transport_error_cb_t tp_error_callbacks[OSIP_TRANSPORT_ERROR_CALLBACK_COUNT];
Osip lib will call these callbacks when the transport layer meet error.
int (*cb_send_message) (osip_transaction_t *, osip_message_t *, char *,
int, int);
Osip lib will call this callback to do the real transportation of the message.
eXosip set these callbacks in eXosip_set_callbacks.
osip_init
init 4 types of transaction state machine:
set transition_t list:
typedef struct _transition_t
{
state_t state;
type_t type;
void (*method) (void *, void *);
}
transition_t;
It set the process method for a type of event in a type of state
for example, in __ict_load_fsm ():
transition = (transition_t *) osip_malloc (sizeof (transition_t));
transition->state = ICT_PRE_CALLING;
transition->type = SND_REQINVITE;
transition->method = (void (*)(void *, void *)) &ict_snd_invite;
osip_list_add (ict_fsm->transitions, transition, -1);
How to process the SIP message
TU calls some functions to queue osip_event to the fifo of the transaction.
TU calls funtions, such as osip_ict_execute, which calls osip_transaction_execute to handle the osip_event in fifo:
osip_transaction_execute first find the type of event, and then get that type of fsm, and then call fsm_callmethod
fsm_callmethod will find the transition according to event type and transaction state, and the call transition->method
call eXosip and eXosip_listen_addr
poll the event periodly
It’s based on osip lib. It implements transport layer which is defined by RFC3261
The eXosip doesn’t wrapp the osip library. It just provides a transport layer for supporting message transfer.
eXosip_t structure
struct eXosip_t
{
struct eXosip_net net_interfaces[3];
osip_list_t *j_transactions;
osip_t *j_osip;
int j_stop_ua;
void *j_thread;
jpipe_t *j_socketctl; // to notify an request from upper layer is queued to fifo of transaction
jpipe_t *j_socketctl_event; //to notify event to upper layer
osip_fifo_t *j_events; //save event which will be sent to upper layer
};
eXosip_init:
init the struct eXosip
call osip_init to init the struct osip which is a member of eXosip(eXosip.j_osip
set osip lib callback: eXosip_set_callbacks (osip):
cb_snd_message is most important callback
create two pipe(eXosip.j_socketctl and eXosip.j_socketctl_event)
init fifo: osip_fifo_init(eXosip.j_events)
j_stop_ua is used to indicate whether thread should be stopped (used in _eXosip_thread)
eXosip_listen_addr:
listen on a port for SIP message
call _eXosip_thread
_eXosip_thread:
eXosip_read_message use select to wait for the message from upper layer or network
call osip_timers_ict_execute, osip_timers_nict_execute osip_timers_ist_execute and osip_timers_nist_execute to handle transaction timeout
call osip_ict_execute ,osip_nict_execute, osip_ist_execute and osip_nist_execute to handle the event in transaction FIFO
eXosip_process_newrequest is used to init UAS transaction
(eXosip_call_send_initial_invite is used to init UAC transaction)
for outgoing message:
build SIP message, put to the transaction fifo by calling OSIP API
then write something to pipe to notify _eXosip_thread to handle transaction
for incoming message:
_eXosip_thread is listening to the incoming socket, if there is a incoming message,
the _eXosip_thread will be waken up to create a new transaction, and handle transaction.
eXosip_call_build_initial_invite
eXosip_call_send_initial_invite
eXosip_call_init
osip_transaction_init to init a ICT transaction
osip_new_outgoing_sipmessage to create a osip event
osip_transaction_add_event to add event to transaction FIFO
__eXosip_wakeup to wake up _eXosip_thread to handle the event
_eXosip_thread call osip_ict_execute, osip_ict_execute call osip_transaction_execute to find the type of event, get that type of fsm, and then call fsm_callmethod to handle the event. As the above description, fsm_callmethod will find the transition according to event type and transaction state, and the call transition->method. For ICT transaction in ICT_PRE_CALLING state, __ict_load_fsm set method to ict_snd_invite
ict_snd_invite will call osip-> cb_send_message, which is set by eXosip_set_callbacks as cb_snd_message
cb_snd_message will send the message to remote peer. _eXosip_thread will wait for remote response, and call osip_ict_execute to handle the response. The transaction state machine will be changed to different state according to the response. Meanwhile, the state machine will call callback set by eXosip_set_callbacks to notify eXosip state change. When eXosip receive the notification, eXosip will send eXosip-defined event to upper layer by queuing it to j_events. Upper layer applilcation which should call eXosip_event_wait to wait for events will get event, and handle it. Please refer to the example application UCT IMS Client.
4 The process to receive an incoming message
It is processed in _eXosip_thread:
receives the incoming message
eXosip_process_newrequest to create a new transaction, put to transaction FIFO
osip_ist_execute will handle the event
the following process is similar to osip_ict_execute described on the section 3.