【正文】
..............................................................................................46 Function Documentation.................................................................................46 Xosip2 SDP helper API...............................................................................................48 Functions.........................................................................................................48 Function Documentation.................................................................................481 The eXtented eXosip stack HowTo initialize libeXosip2.When using eXosip, your first task is to initialize both eXosip context and libosiplibrary (parser and state machines). This must be done prior to any use of libeXosip2.include eXosip2/int i。TRACE_INITIALIZE (6, stdout)。i=eXosip_init()。if (i!=0)return 1。i = eXosip_listen_addr (IPPROTO_UDP, NULL, port, AF_INET, 0)。if (i!=0){eXosip_quit()。fprintf (stderr, could not initialize transport layer\n)。return 1。}... then you have to send messages and wait for eXosip events...In the previous code, you39。ve learned how to:? Initialize the osip trace (pile this code with DENABLE_TRACE)? Initialize eXosip (and osip) stack? Open a socket for signalling (only UDP with initial eXosip2 version)Now you have to handle eXosip events. Here is some code to get eXosip_event from the eXosip2 stack. eXosip_event_t *je。for (。){je = eXosip_event_wait (0, 50)。eXosip_lock()。eXosip_automatic_action ()。eXosip_unlock()。if (je == NULL)break。if (jetype == EXOSIP_CALL_NEW){........}else if (jetype == EXOSIP_CALL_ACK){........}else if (jetype == EXOSIP_CALL_ANSWERED){........}else .............eXosip_event_free(je)。}You will receive one event for each SIP message sent. Each event contains theoriginal request of the affected transaction and the last response that triggers theevent when available.You can access all headers from those messages and store them in your own contextfor other actions or graphic displays.For example, when you receive a REFER request for a call transfer, you39。ll typicallyretreive the referTo header:osip_header_t *referto_head = NULL。i = osip_message_header_get_byname (evtsip, referto, 0,amp。referto_head)。if (referto_head == NULL || referto_headhvalue == NULL)The eXosip_event also contains identifiers for calls, registrations, iningsubscriptions or outgoing subscriptions when applicable. Those identifiers are used inAPI to control calls, registrations, ining or outgoing subscriptions. These API willbuild default messages with usual SIP headers (From, To, CallID, CSeq, Route,RecordRoute, MaxForward...) and send thoses messages for you. HowTo initiate, modify or terminate calls.eXosip2 offers a flexible API to help you controling calls. Initiate a callTo start an outgoing call, you typically need a few headers which will be used byeXosip2 to build a default SIP INVITE request. The code below is used to start a call:osip_message_t *invite。int i。i = eXosip_call_build_initial_invite (amp。invite,sip:to@,sip:from@,NULL, // optionnal route headerThis is a call for aconversation)。if (i != 0){return 1。}osip_message_set_supported (invite, 100rel)。{char tmp[4096]。char localip[128]。eXosip_guess_localip (AF_INET, localip, 128)。snprintf (tmp, 4096,v=0\r\no=josua 0 0 IN IP4 %s\r\ns=conversation\r\nc=IN IP4 %s\r\nt=0 0\r\nm=audio %s RTP/AVP 0 8 101\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:101 telephoneevent/8000\r\na=fmtp:101 011\r\n, localip, localip, port)。osip_message_set_body (invite, tmp, strlen (tmp))。osip_message_set_content_type (invite, application/sdp)。}eXosip_lock ()。i = eXosip_call_send_initial_invite (invite)。if (i 0){eXosip_call_set_reference (i, reference)。}eXosip_unlock ()。return i。The above code is using eXosip_call_build_initial_invite to build a default SIP INVITErequest for a new call. You have to insert a SDP body announcing your audioparameter for the RTP stream.The above code also show the flexibility of the eXosip2 API which allow you to insertadditionnal headers such as Supported: 100rel (announcing support for a SIPextension). Thus you can enterely control the creation of SIP requests.The returned element of eXosip_call_send_initial_invite is the call identifier that youcan use to send a CANCEL. In future events other than 100 Trying, you39。ll also get thedialog identifier that will also be needed to control established calls.eXosip_call_set_reference is also a mean to attach one of your own context to a callso that you39。ll get your pointer back in eXosip_event. Answer a callThe code below is another example that teach you how to answer an ining call.You39。ll usually need to send a 180 Ringing SIP answer when receiving a SIP INVITE:eXosip_lock ()。eXosip_call_send_answer (catid, 180, NULL)。eXosip_unlock ()。Note: The above code also shows that the stack is sometimes able to build and senda default SIP messages with only one API callThen, when the user wants to answer the call, you39。ll need to send a 200 ok and inserta SDP body in your SIP answer:osip_message_t *answer = NULL。eXosip_lock ()。i = eXosip_call_build_answer (catid, 200, amp。answer)。if (i != 0){eXosip_call_send_answer (catid, 400, NULL)。}else{i = sdp_plete_200ok (cadid, answer)。if (i != 0){osip_message_free (answer)。eXosip_call_send_answer (catid, 415, NULL)。}elseeXosip_call_send_answer (catid, 200, answer)。}eXosip_unlock ()。Note: In the above code, you can note that to send a response to a request, you haveto use the transaction identifier (and not a call identifier or a dialog identifier!)Note2: For sending a 200ok, you39。ll usually need to insert a SDP body in the answerand