Reference: http://mbstudio.spaces.live.com/blog/cns! C898c3c401_dc11! 955. Entry
For the latest version of this document and the relevant source code and vc6 engineering files mentioned in this article, please find them on this site ~~
(In the skydriver public folder on the homepage, you may need to useProxyCan access the space normally-the space is absolutely stable and files will not be lost !)
(The focus of recent work is not on SIP development, so this document has no chance to be updated. If you have any technical questions, please consult others as much as possible. I may not reply in time .)
I have never been able to study Osip carefully. Recently, I have seen that the version has reached version 3.x. I have seen many help instruction manuals on the Internet being too old and many documents may be suspicious of incorrect content ~~
In Linux, the compilation and usage of Osip should be very simple. The Install instruction document also describes the usage of Osip in the vc6.0 Development Environment on Windows.
Although Osip developers also explained that Osip only uses the Standard C Development Library, the first step is stuck when many users use Osip in windows, without the Lib library and dll library of Osip, there is no way to use Osip in your own program. So the first step is to learn how to obtain the static and dynamic link library of Osip, so that our own programs can use them to successfully compile and execute our programs.
Stage 1:
------------------------------------------------------
Create a new project first. Many documents on the internet describe how to create a Win32 dynamic link library project. Here we will also create a blank project to save it.
Similarly, copy all the files in the osipparser2 directory under the src directory of osip2 version 3.0.1 to the root directory of the project we just created and operate on vc6:
Project-add to project-Files
Add all source programs and header files to the project to save the project.
At this time, we can try to compile the project, and you will get a lot of error messages, the content is nothing more than the osipparser2/XXXXX. h header file and so on.
Processing: in Linux, we usually copy the header file and Lib library to a directory such as/usr/inclue;/usr/lib, and directly write # include <XXX in the C source program. h>, you can find them directly. In VC, the same, the simplest method is to copy the osipparser2 directory under the include directory in the osip2 source package to the default include directory in windows, this directory is set in tool-options-directories of vc6. (If you know this step, you do not need to copy the file, you can directly add the directory where the Osip source code package is located). By default, if it is installed on the C disk, the directory is C:/program files/Microsoft Visual Studio/vc98/include.
At this time, we will re-compile our project, smoothly compile and generate osipparser2.dll. At this time, many documents on the Internet may directly say that this step will also generate the libs directory, which contains the osipparser2.lib file, but we didn't generate it here :)
The simplest method is to directly create a project without further research. Create a Win32 static Link Library Project and compile it directly to obtain osipparser2.lib.
------------------------------------------------------
Above, we have obtained the Osip parser development library. Next we will compile the complete Osip protocol stack development library, and create the dynamic and static link library projects respectively according to the above method, replace the file to be copied with the file under the Osip directory under SRC and The oSIP directory under the include directory to get osip2.dll and osip2.lib.
The compilation of osip2.dll may cause another error. The content means that the link library cannot be found. Therefore, we need to copy the previously compiled osipparser2.lib To The oSIP project directory, in vc6, perform the following operations:
Object/library modules in project-setting-link:
The contents such as kernel32.lib user32.lib... xxx. Lib are added at the end: osipparser2.lib
Save the project and compile it again to compile osip2.dll.
------------------------------------------------------
So far, we have obtained the complete Osip development library. during use, we only need to include the Osip header file in our program, and add osipparser2.lib and osip2.lib to the link parameters of the project.
------------------------------------------------------
Next, let's verify the development library we got and get a rough idea of the Osip syntax specification.
Create a Win32 console program project in VC and copy the C program in the test directory under the src directory of the libosip source package to the project at will, directly compile (add osip2.lib in the Link option according to the preceding method in the Project Settings, and osipparser2.lib references the previously compiled static library file) to run (with parameters, the parameter is generally a text file, and you can copy a plain text file with the same name as the source file to the project directory from the res directory of the test directory ).
Several files in this directory basically test some basic function functions of Osip, such as URI parsing. You can get a rough idea of Osip syntax specifications and calling methods, at the same time, it can also verify whether the previously compiled Osip development library can be used normally. After this project is completed successfully, you can proceed to the next step to learn how to use Osip.
------------------------------------------------------
Because Osip is a relatively low-level implementation of the SIP protocol stack, it is difficult for beginners to get started, and most of the official examples are pseudo code. You need to refer to the actual examples and programs, the best example is the officially released Osip extension library exosip2, which allows you to quickly create a complete sip program using exosip (applicable only to the development of SIP terminals, so here we just use it to quickly develop a SIP terminal to learn Osip more conveniently. to really master the development of SIP, We need to master Osip and read the RFC documentation carefully, exosip is not our ultimate learning goal). By successfully compiling and running a self-developed program, furthermore, it should be the best learning method for beginners to create their own sip program by using the exosip development library. After getting familiar with it, I will use another function to learn more about the interface functions provided by exosip, in this way, you can gain an in-depth understanding of Osip to indirectly learn Osip. At the same time, you can also learn from exosip to correctly use Osip's good programming style and syntax format.
And to successfully compile exosip, it seems that many people are hard to get, directly on the XP-sp2, with vc6, although you use the exosip recommended winsock2.h, but will get a sockaddr_storage structure unrecognized error, because the Development Library of vc6 is too old, you need to upgrade the Platform SDK of the system, as shown below:
Http://www.microsoft.com/msdownl... psp2fullinstall.htm (vc6 support has stopped, this is the latest SDK vc6 can use)
Before compilation, you need to add the osip_mt macro to enable the thread library. Otherwise, errors will occur when you use the exosip library in the program, and many undefined warnings will be generated during compilation, compile exosip2.lib for our use. Of course, we need to successfully compile osip2 and osipparser2 before that. In actual use, we find that osip_mt macros need to be added to Osip, otherwise, an error occurs when osip_mt calls the Osip thread library, so we need to re-compile Osip :), because exosip is based on Osip (the same method is used to create static and dynamic link library projects, manually add the Lib library of Osip and osipparser to link ).
------------------------------------------------------
Creating a new project can be any project. We started from the simplest Win32 console program. To successfully use Osip, We need to reference the relevant library, call the relevant header file, and perform multiple experiments, the following libraries must be referenced:
Exosip2.lib osip2.lib osipparser2.lib wsock32.lib iphlpapi. Lib ws2_32.lib dnsapi. Lib
Among them, except the three Osip libraries compiled above, other libraries are system libraries, some of which are newly provided by the newly installed Platform SDK.
Now, we have a simple development environment. We can take full advantage of a large number of Osip-based code snippets and official instructions on the Internet to test and use specific function functions :)
------------------------------------------------------
We first implement a simple pure sip signaling (without voice connection) the test of UAC's SIP terminal program development (that is, a SIP Soft Phone model that can only be called but cannot be called), we create an MFC application, dialog box mode, as described above, the setup project contains the Osip-related development libraries and SDK development libraries we obtained above, and because of the default libc conflicts, you need to exclude the msvcrt [d] development library (where D represents the debug mode, and D represents the release mode ), you can directly use several main functions of exosip to create a basic SIP Soft Phone model.
The main process is:
Initialize exosip library-start event listening thread-register with SIP proxy-initiate a call to a SIP terminal (phone number)-establish connection-end connection
Initialization code:
Int ret = 0;
Ret = exosip_init ();
Exosip_set_user_agent ("# youtoo0.1 ");
If (0! = RET)
{
Afxmessagebox ("couldn't initialize exosip! /N ");
Return false;
}
Ret = exosip_listen_addr (ipproto_udp, null, 0, af_inet, 0 );
If (0! = RET)
{
Exosip_quit ();
Afxmessagebox ("couldn't initialize transport layer! /N ");
Return false;
}
Start the event listening thread:
Afxbeginthread (sip_uac, (void *) This );
Register with the SIP Proxy:
Exosip_clear_authentication_info ();
Exosip_add_authentication_info (uname, uname, upwd, "MD5", null );
Real_send_register (30);/* for user-defined function code, see source code */
Initiate a call (construct a false SDP description and use it to build an RTP media connection ):
Osip_message_t * invite = NULL;/* Call initiation message body */
Int I = exosip_call_build_initial_invite (& invite, dest_call, source_call, null, "## youtoo test demo! ");
If (I! = 0)
{
Afxmessagebox ("intial invite failed! /N ");
}
Char localip [128];
Exosip_guess_localip (af_inet, localip, 128 );
Snprintf (TMP, 4096,
"V = 0/R/N"
"O = Josua 0 0 in ip4 % S/R/N"
"S = conversation/R/N"
"C = in ip4 % S/R/N"
"T = 0 0/R/N"
"M = audio % s RTP/AVP 0 8 101/R/N"
& Quot; A = rtpmap: 0 PCMU/8000/R/N & quot"
"A = rtpmap: 8 PCMA/8000/R/N"
"A = rtpmap: 101 telephone-event/8000/R/N"
"A = fmtp: 101 0-11/R/N", localip, localip, "9900 ");
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 );
Exosip_unlock ();
Hanging up or canceling a call:
Int ret;
Ret = exosip_call_terminate (call_id, dialog_id );
If (0! = RET)
{
Afxmessagebox ("hangup/terminate failed! ");
}
We can see that it is very simple. With the help of the ortp and mediastreamer development libraries, we can quickly add RTP and system voice API interface interaction and voice encoding functions for our SIP Soft phones, that is to say, you can quickly develop an available SIP Soft Phone. The introduction to ortp and mediastreamer is not the focus of this article. We will consider adding relevant tutorials when we are free, you can download the VC source code project file of the basic available complete SIP Soft Phone for your reference. It is completely Copyleft. You are welcome to reprint it, but please indicate the author's information when you reprint it. Thank you!
Stage 2:
---------------------------------------------------
After obtaining a SIP Soft Phone model, we can analyze the code based on the actual running performance of the Soft Phone (combined with Ethereal packet capture analysis, to achieve the ultimate goal of using exosip to help us learn Osip (for example, to quickly develop an available SIP Soft Phone, go to the Forum mentioned above to download a basic complete and available SIP Soft Phone that is quickly built using ortp and mediastreamer # reference for the VC source code project file of youtoo 0.1 ).
Now, starting from the initialization function of exosip, we can analyze the usage of Osip. This is the second stage. The third stage is to thoroughly learn the source code of Osip, but in most cases it should be unnecessary, in the second stage, some work in the third stage is involved, and the source code of Osip is mostly the Syntax Parsing of some sip data and the implementation of the state machine. After a deep understanding of the SIP protocol, these are just a way of implementation. You don't have to accept them completely. Instead, you can use your own methods and styles to achieve a set. For example, you can use lighter and more purposeful methods, osip only serves as a reference.
Exosip_init () is the initialization function of exosip. Let's take a look at its internal implementation:
The first line is the definition of osip_t * Osip, which we can see in the Osip official manual that all programs that use Osip must declare an osip_t pointer at the very beginning, and use osip_init (& Osip) to initialize this pointer. Destroy this resource and use osip_release (Osip.
We can see a lot of osip_trace in the Code. This is the function osip_trace called by the debug output macro. You can use the enable_trace macro to enable debugging to facilitate our development and debugging.
Others are some initialization operations of exosip_t global variable exosip, including the top memset (& exosip, 0, sizeof (exosip) completely cleared and similar exosip. user_agent = osip_strdup ("exosip/" exosip_version. j_stop_ua = 0 should be a state machine switch. Many codes can be found later to check this variable to determine whether to proceed with the process. The default value 0 indicates that the processing process of exosip is now ready, that is, UA is not stop.
Osip_set_application_context (Osip, & exosip) is interesting. When the following exosip_set_callbacks (Osip) sets a large number of callback functions for Osip, this allows Osip to access a large amount of interaction information set in the global variable exosip, which is equivalent to when we open a thread under VC, A void pointer passed to the thread points to the current diid object instance of our MFC application. You can use the void * osip_get_application_context (osip_t * Osip) function to retrieve the pointer for use, however, it seems that exosip does not use it, but it may be left for personal extension :)
We can also see the sock initialization code on the Win32 platform before the initialization code. We can know that exosip is a native Winsock API function, that is, when we used to write sock programs using VC and winapi (instead of MFC), we used the sock initial code and an interesting piece of code, namely, the jpipe () function, they return a pipeline, an array with two integer values (one in and one out), view its code and find that non-Win32 platforms are directly using pipe system functions, in Win32, the pipeline is simulated by using a pair of TCP local sock connections. One sock writes one sock read, and this Code is of reference value :)
J = 50;
While (aport ++ & J --> 0)
{
Raddr. sin_port = htons (short) aport );
If (BIND (S, (struct sockaddr *) & raddr, sizeof (raddr) <0)
{
Osip_trace (_ file __, _ line __, osip_warning, null,
"Failed to bind one local socket % I! /N ", aport ));
} Else
Break;
}
Meaning: Check 50 ports in sequence, from static int aport = 10500; that is, 10500 ~ Port 10550 finds an available local port to bind a pair of sock of the listen analog pipe.
Exosip_set_callbacks (Osip) is nothing nice, just like what is described in the Osip official documentation. The key to setting up a lot of callback functions is the implementation of callback functions, this is also the main reason for many beginners to use Osip to get stuck. I don't know how the program built by Osip runs. Just select a few callback functions to see how exosip is implemented, there are many functions in the following format:
Static void
Cb_sndbye (INT type, osip_transaction_t * TR, osip_message_t * SIP)
{
Osip_trace (osip_trace
(_ File __, _ line __, osip_info3, null, "cb_sndbye (ID = % I)/R/N ",
Tr-> transactionid ));
}
That is to say, I just printed the debugging and didn't fully implement any functions. We can use the same method to define a lot of callback functions when learning. I am not busy thinking about how to implement them completely, first, only the debugging information is printed, and the specific application logic is analyzed based on the packet capture test and the debugging result shows which callback the program has taken and which callback is called, to understand the purpose of a specific callback function, it is much more convenient to implement the Code. Of course, if you see the RFC documentation, you should be able to understand the purpose of each callback function literally, this is a post, and not anyone can quickly fully understand the RFC, so we should refer to exosip :)
We analyze the important callback functions one by one:
---------------------------
Osip_set_cb_send_message (Osip, & cb_snd_message) Callback Function for sending SIP messages
This function may be one of the most important callback functions. Message sending, including request messages and response messages, is generally controlled by the state machine, initiate a message to initialize a state machine, respond to a message to modify the state machine, and end the message sending and ending state machine ......
The main code of cb_snd_message is to analyze the message osip_message_t * sip to be sent in the parameter to find out the real char * host to be sent, int port value (these parameters can be omitted, but the host and port must be used to send messages, so it must be parsed from the SIP ), finally, the function cb_udp_snd_message and cb_tcp_snd_message for sending the final message based on the transmission method parsed in the SIP is TCP or UDP (their parameters are consistent, that is, this function only supplements some omitted parameters and checks the validity of messages ).
** After all, exosip is a common development library. It takes into account various complex environments that support TCP, UDP, TCPS, IPv4, IPv6, Win32, * nix, and wince. Therefore, we can skip what we do not need for the moment, for example, IPv6-related code implementation.
Because we use UDP in most cases, let's take a look at the implementation of cb_udp_snd_message. It gets available sock from the global variable exosip, and parse the host and port (?? Isn't the previous function completely parsed ?? If no port information exists, the default value is 5060. Use osip_message_to_str (SIP, & message, & length) the formatted SIP message to be sent by the function is converted to simple data that can be transmitted using sock and sent to complete message sending. The Code contains many complex environment detection and error control, etc, we don't need to pay too much attention for the time being. We can continue down. There is a keeplive code at the end. From the code literal analysis, it may be the automatic re-sending of the relevant code of the SIP register message, you can refine the analysis later.
The cb_tcp_snd_essage function implementation is much simpler than the preceding UDP implementation, mainly in the environment detection error control aspect, because after all, TCP is a stable connection, compare the code, we can see that the main process is to convert the SIP message and send it to the target of the host and port parsed from the SIP message.
After reading the two functions, we can know that exosip requires two sock, an array, 0 for UDP, 1 for TCP, and sock for initialization, the above section describes the network-related initialization of exosip. The above exosip_init can be regarded as the system initialization of this development library :)
To some extent, we should know where the message of the SIP application developed by Osip is sent. By the way, from this callback function, it is difficult to start with everything, just like when developing a Win32 application, it is easy to find the work under the main function entry of the Win32 program. The following are the corresponding processing functions developed for some event messages :)
Osip_set_kill_transaction_callbackTransaction termination callback function
Corresponds to the end of the ICT, ist, NICT, NIST Client/Server registration/non-registration transaction state machine, mainly using osip_remove_transaction (exosip. j_osip, TR) deletes the current tr transaction, and adds a series of cleanup work. Among them, NICT is a complicated cleaning of non-invite transactions on the client, and there are more to be processed, you can perform necessary cleanup based on the actual application situation :)
Cb_transport_error callback for failed Transmission
It corresponds to the four transaction state machines mentioned above. If they fail to be processed, they will be processed in a unified manner.
It can be seen from the code that only when the notify, subscribe, and option operations fail to be processed, other errors can be ignored directly.
Osip_set_message_callback callback for message sending and Processing
Different Types indicate different message sending statuses
Osip_xxx_again resend related messages
Osip_ict_invite_sent initiates a call
Osip_ict_ack_sent ack response
Osip_nict_register_sent initiates registration
Osip_nict_bye_sent bye issued
Osip_nict_cancel_sent cancel issued
Osip_nict_info_sent, osip_nict_options_sent, osip_nict_subscribe_sent, osip_nict_policy_sent, osip_nict_unknown_request_sent
We can see that exosip does not process them any more. We can record the logs before resending 2XX messages as needed, and expand the retransmission processing method, record the call logs before initiating an invite.
Osip_ict_status_1xx_received UAC receives the 1xx message, which generally indicates that the correct state is being processed. In this case, it mainly sets the state value of the transaction state machine, some parameters of The oSIP in the session are set based on the returned value. There are many conditions to judge, but we usually use the 100,180,183 judgment. For the moment, we can ignore the complicated judgment code.
Osip_ict_status_2xx_received UAC receives the 2XX message. Here, we track the 2XX message in register, indicating that the registration is successful. At this time, the registration field value of exosip is updated to enable exosip to automatically maintain UAC registration, the 2XX response of bye is the final message. The 2XX response of invite mainly initializes session-related data, indicating that the connection has been established successfully.
The other 4xx, 5xx, and 6xx are corresponding processes respectively. You can view the summary Based on the implementation.
Report_event (JE, SIP) is a function used for event processing in the Code. After tracking, we found that it eventually uses the jpipe pipeline we mentioned above, this allows you to observe the processing information in the state machine in real time outside the state machine.
Osip_nist_status_xxx_sent corresponds to the UAC processing above. Here, it is the message processing corresponding to UAS, Which is simpler than UAC.
The previous section briefly introduced a large number of callback functions and their summary processing logic, which may be confusing. You don't have to worry about it for the time being. You just need to remember a rough image, knowing that a sip processing program is passed throughOsip_set_cb_send_messageThe callback function is used to actually send various SIP messages, and the standard transaction model of SIP is implemented by Osip, we only need to set different callback handler functions for different transaction statuses to process the transaction. The specific State Changes and internal logic can be left empty.
Next, let's take a look at the sock initialization function used by the message processing callback function, that is, the network initialization function exosip_listen_addr that we mentioned above besides system initialization:
As you can see above, the system will initialize Two sock, one UDP and one TCP, but check the code and find that there is a third TCPS, but it seems that it is not practical, the code first sets the corresponding array value based on whether the transmission is UDP or TCP, and if the IP address and port number are not provided, the system automatically retrieves the local network interface and creates an available sock (http_port mode is not required ).
After sock initialization, how do I start the SIP transaction? See this call exosip. j_thread = (void *) osip_thread_create (20000, _ exosip_thread, null), right, a thread is enabled here, that is, exosip is the state machine logic that calls the thread function of Osip (the thread function provided by the system is not used for cross-platform processing) for transaction processing, in this way, we can see why we haven't been able to see the startup code of the Program executed in sequence. Next we can see that the actual processing function of the thread is _ exosip_thread. In this code, we can see the state machine control switch variable while (exosip. j_stop_ua = 0), that is, when j_stop_ua is set to 1, osip_thread_exit () ends the transaction processing, that is, the program is terminated. Next, we can see that _ exosip_execute is the final processing function, in addition, the logic is always executed without the end of the program. Note that you must enable the osip_mt multi-thread macro of Osip.
The Code of _ exosip_execute contains many time functions and variables. Take a closer look. Apart from some control code, the main processing function is exosip_read_message (1, lower_ TV. TV _sec, lower_ TV. TV _usec, 1 indicates that only one message is taken out. The code size is very large, but in the same way, many of them control code and error detection code. We can temporarily ignore them when viewing them.
When the exosip_read_message reads a message, no sock block or non-block method is used, but the select method is used. For specific applications, You can query documents related to fd_set.
According to jpipe_read (exosip. j_socketctl, buf2, 499). we can estimate that the buf2 should be the data stored in our control pipeline. The specific functions have not yet been shown, it should be used to reflect information such as alerts in some state machines. The actual state machine data processed by the SIP is stored in the Buf and obtained using _ exosip_recvfrom, after sipevent = osip_parse (BUF, I) is obtained, use osip_find_transaction_and_add_event (exosip. j_osip, sipevent) to query the transaction state machine corresponding to the event. After finding it, as described in its annotation,/* handled by Osip! */, That is, the many callback functions we set above. Now we know the general process of processing the entire sip application.
What if the transaction state machine is not found? Directly discard it? No. If this is a response message, but no transaction state machine processes it, it is an error. It must be cleared before it can be discarded. If it is a request, it cannot be discarded because the UAS transaction status machine needs to be created by it (response message indicates that a request message is sent locally, that is, UAC action, the transaction state machine should be started by initiating UAC code initialization.) the entire logic should be very simple, but there are a lot of exosip implementation code, it can be seen that it has spent a lot of energy to ensure the stability of the session and cope with network complexity, we can perform a lot of streamlining on it to build a code implementation that meets our needs.
First, let's look at the processing function exosip_process_response_out_of_transaction of the Error Response Message. We can see that its code is a lot of value assignment statements, xxx = NULL, which clears a lot of runtime variables and then calls osip_event_free to clear events, or in some complex cases, you need to parse the current runtime data, analyze the "possibly" peer that is waiting for the response, and send the relevant Termination notification message, it can be simplified as needed.
Request event processing exosip_process_newrequest. First, it detects the event. msg_is_invite, msg_is_ack, msg_is_request ......, Classify the state machine of the event, and then use _ exosip_transaction_init (& transaction, (osip_fsm_type_t) tx_type, exosip. j_osip, EVT-> SIP) initialize the state machine based on the test results. The actual call is osip_transaction_init. After initialization, the event will be input to the state machine osip_transaction_add_event (transaction, EVT ), after automatic processing by the state machine, the corresponding callback function processing logic is called. Of course, in order to facilitate the rapid development of SIP terminal applications, exosip adds a lot of automated processing code below to distinguish it from the processing code we set in the callback function.
The event processing function code called by the thread is
If (exosip. keep_alive> 0)
{
_ Exosip_keep_alive ();
}
This Code confirms that keep_alive is used to set whether to automatically re-register, the _ exosip_keep_alive function automatically resolves the registration message stored in the exosip global variable and then automatically initiates a register registration to the SIP server as needed.
Similarly, because the registration message initiation is a UAC action, put it here. It can be seen that the transaction state machine processing of all event messages is here, but only the UAS transaction state machine is created here, the transaction state machine of UAC is created and found below. From our youtoo soft phone code, we can see that exosip_call_send_initial_invite is called for the call initiation and registration, respectively, exosip_register_send_register (two other BUILD functions are used to construct the SIP messages to be sent by the two send functions respectively, the UAC transaction processing state machine is initialized here.
Exosip_register_send_register indicates _ exosip_transaction_init (& transaction, NICT, exosip. j_osip, Reg) initializes the UAC state machine, which is also the same as the osip_transaction_init function called by UAS. Similarly, osip_transaction_add_event (transaction, sipevent) is used to import the event into the state machine, the state machine will then automatically process the processing logic of calling the corresponding callback function.
In addition, osip_new_outgoing_sipmessage (REG) indicates sending messages. Here, we can understand that the actual sending operation is to be processed by the state machine, the callback function of message sending is called to send the registered message.
The same registered message is sent. It is a NICT state machine, and the call message is sent by ICT, which is processed by exosip_call_send_initial_invite, _ exosip_transaction_init (& transaction, ICT, exosip. j_osip, invite) initializes the state machine. Before that, an exosip_call_init parameter is used to initialize some parameters of exosip. For the moment, no matter it, the same osip_new_outgoing_sipmessage (invite) sends a call message, however, it is still necessary to call the message sending callback function after processing the state machine to actually send the call request function. osip_transaction_add_event (transaction, sipevent) is used to import the event to the state machine in a standard way, the state machine can process subsequent application logic and call the corresponding callback function.
Well, after so many analyses, we learned how exosip calls Osip to form a new call that I can easily call. We can see that in order to achieve the maximum cross-platform and compatibility, there are a lot of test code in the code, macro definition and error re-processing code, it looks very difficult, but understand its main call framework:
Initialization, callback function settings, startup of UAC and UAS transaction processing state machine, and event processing process can basically understand the main functions and correct usage of Osip functions. Next, you can refer to exosip for an application to remove a large amount of code that is temporarily unavailable to build a simple SIP Soft Phone Number and SIP server, so as to further deepen the Osip Learning application.