An example of UAC and UAS implemented using exosip (successful debugging)

Source: Internet
Author: User
After a period of study, I finally had a certain understanding of the SIP. During the learning process, I encountered too many problems, such as being depressed and disappointed. But I bit my teeth and came back. I was touched by the fact that I met some very enthusiastic friends on the Internet and gave me some questions without interrupting them. Thanks to them, especially the friendly big dog, I hope he will see this article one day.
I developed it using the exosip protocol stack. I wrote a <simple SIP call example> online, but it seems that there are some problems. For Beginners, we can get a good example, and the understanding of SIP can get twice the result with half the effort. So I will take out my own example for your reference. If you have any questions, please correct me.
You only need to correct and compile the IP address.

/*************************************** ***
Compilation Method:
Gcc xxx. C-o XXX-lexosip2
****************************************/
/******************* UAS ******************* **********************************
This article can be reproduced at will, but the source must be retained
Author: rainfish
Web: http://blog.csdn.net/bat603/
Test environment: exosip3.0.1/Redhat as 4
**************************************** ***********************************/
# Include <exosip2/exosip. h>
# Include <osip2/osip_mt.h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <netinet/in. h>
# Include <sys/socket. h>
# Include <sys/types. h>

Int
Main (INT argc, char * argv [])
{
Exosip_event_t * Je = NULL;
Osip_message_t * ACK = NULL;
Osip_message_t * invite = NULL;
Osip_message_t * answer = NULL;
Sdp_message_t * remote_sdp = NULL;

Int call_id, dialog_id;
Int I, J;
Int ID;
Char * sour_call = "SIP: 133@192.168.0.133 ";
Char * dest_call = "SIP: 140@192.168.0.140: 5060 ";

Char command;
Char TMP [4096];
Char localip [128];

Int Pos = 0;

// Initialize the SIP
I = exosip_init ();
If (I! = 0)
{
Printf ("can't initialize exosip! /N ");
Return-1;
}
Else
{
Printf ("exosip_init successfully! /N ");
}

I = exosip_listen_addr (ipproto_udp, null, 5060, af_inet, 0 );
If (I! = 0)
{
Exosip_quit ();
Fprintf (stderr, "exosip_listen_addr error! /Ncouldn't initialize transport layer! /N ");
}

For (;;)
{
// Listen for message arrival
Je = exosip_event_wait (0, 50 );

// The protocol stack carries this statement. The specific function is unknown.
Exosip_lock ();
Exosip_default_action (JE );
Exosip_automatic_refresh ();
Exosip_unlock ();

If (JE = NULL) // No message is received
Continue;
// Printf ("the CID is % s, did is % s/n", je-> did, je-> CID );
Switch (Je-> type)
{
Case exosip_message_new: // new message arrival
Printf ("exosip_message_new! /N ");
If (msg_is_message (Je-> request) // If the received message type is message
{
{
Osip_body_t * body;
Osip_message_get_body (Je-> request, 0, & Body );
Printf ("I get the MSG is: % s/n", body-> body );
// Printf ("the CID is % s, did is % s/n", je-> did, je-> CID );
}
// According to the rule, you need to reply to the 200 OK message
Exosip_message_build_answer (Je-& gt; tid, 200, & answer );
Exosip_message_send_answer (Je-& gt; tid, 200, answer );
}
Break;
Case exosip_call_invite:
// Obtain the Message Details.
Printf ("received a invite MSG from % s: % s, username is % s, password is % s/n", je-> request-> req_uri-> host,
Je-> request-> req_uri-> port, je-> request-> req_uri-> username, je-> request-> req_uri-> password );
// Obtain the message body. The message is in SDP format.
Remote_sdp = exosip_get_remote_sdp (Je-> did );
Call_id = Je-> CID;
Dialog_id = Je-> did;

Exosip_lock ();
Exosip_call_send_answer (Je-> tid, 180, null );
I = exosip_call_build_answer (Je-> tid, 200, & answer );
If (I! = 0)
{
Printf ("this request MSG is invalid! Cann' t response! /N ");
Exosip_call_send_answer (Je-> tid, 400, null );
}
Else
{
Snprintf (TMP, 4096,
"V = 0/R/N"
"O = anonymous 0 0 in ip4 0.0.0.0/R/N"
"T = 1 10/R/N"
"A = Username: rainfish/R/N"
"A = password: 123/R/N ");

// Set the response SDP message body and analyze the message body in the next step.
// Directly reply to the original message without analyzing the message body.
Osip_message_set_body (answer, TMP, strlen (TMP ));
Osip_message_set_content_type (answer, "application/SDP ");

Exosip_call_send_answer (Je-& gt; tid, 200, answer );
Printf ("Send 200 over! /N ");
}
Exosip_unlock ();

// Display the attribute content in the SDP message body, which is scheduled to store our information
Printf ("the info is:/N ");
While (! Osip_list_eol (remote_sdp-> a_attributes, POS ))
{
Sdp_attribute_t *;

At = (sdp_attribute_t *) osip_list_get (remote_sdp-> a_attributes, POS );
Printf ("% s: % s/n", At-> a_att_field, At-> a_att_value ); // The reason why attribute a must be stored in the SDP message body must be two columns

Pos ++;
}
Break;
Case exosip_call_ack:
Printf ("Ack recieved! /N ");
// Printf ("the CID is % s, did is % s/n", je-> did, je-> CID );
Break;
Case exosip_call_closed:
Printf ("the remote hold the session! /N ");
// Exosip_call_build_ack (dialog_id, & ACK );
// Exosip_call_send_ack (dialog_id, ACK );
I = exosip_call_build_answer (Je-> tid, 200, & answer );
If (I! = 0)
{
Printf ("this request MSG is invalid! Cann' t response! /N ");
Exosip_call_send_answer (Je-> tid, 400, null );

}
Else
{
Exosip_call_send_answer (Je-& gt; tid, 200, answer );
Printf ("Bye send 200 over! /N ");
}
Break;

Case exosip_call_message_new: // the difference between this type and exosip_message_new is explained in the source code.
/*
/* Request related events within CILS (Response t invite )*/
Exosip_call_message_new,/** <announce new incoming request .*/
/* Response received ed for request outside cballs */
Exosip_message_new,/** <announce new incoming request .*/
I don't quite understand either. The understanding is: exosip_call_message_new is the arrival of a new message in a call, such as Ring trying. Therefore, after receiving the message, you must determine
This message type, exosip_message_new, indicates that the incoming message is not in the call.
This explanation is for reference only.
*/
Printf ("exosip_call_message_new/N ");
If (msg_is_info (Je-> request) // If the info method is transmitted
{
Exosip_lock ();
I = exosip_call_build_answer (Je-> tid, 200, & answer );
If (I = 0)
{
Exosip_call_send_answer (Je-& gt; tid, 200, answer );
}
Exosip_unlock ();
{
Osip_body_t * body;
Osip_message_get_body (Je-> request, 0, & Body );
Printf ("the body is % s/n", body-> body );
}
}
Break;
Default:
Printf ("cocould not parse the MSG! /N ");
}
}
}
/******************* UAC ******************* **********************************
This article can be reproduced at will, but the source must be retained
Author: rainfish
Web: http://blog.csdn.net/bat603/
Test environment: exosip3.0.1/Redhat as 4
**************************************** ***********************************/

# Include <exosip2/exosip. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include <netinet/in. h>
# Include <sys/socket. h>
# Include <sys/types. h>

Int
Main (INT argc, char * argv [])
{
Exosip_event_t * Je;
Osip_message_t * Reg = NULL;
Osip_message_t * invite = NULL;
Osip_message_t * ACK = NULL;
Osip_message_t * info = NULL;
Osip_message_t * message = NULL;

Int call_id, dialog_id;
Int I, flag;
Int flag1 = 1;
Int ID;

Char x identity = "SIP: 140@192.168.0.140 ";
Char * registerer = "SIP: 192.168.0.133: 5060 ";
Char * source_call = "SIP: 140@192.168.0.140 ";
Char * dest_call = "SIP: 133@192.168.0.133: 5060 ";

Char command;
Char TMP [4096];
Char localip [128];

Printf ("r register with the server/n ");
Printf ("C cancel registration/n ");
Printf ("I initiate a call request/n ");
Printf ("H hanging/n ");
Printf ("Q exit Program/n ");
Printf ("s execution method info/n ");
Printf ("m execution method message/n ");
// Initialization
I = exosip_init ();
If (I! = 0)
{
Printf ("couldn't initialize exosip! /N ");
Return-1;
}
Else
{
Printf ("exosip_init successfully! /N ");
}

I = exosip_listen_addr (ipproto_udp, null, 5060, af_inet, 0 );
If (I! = 0)
{
Exosip_quit ();
Fprintf (stderr, "couldn't initialize transport layer! /N ");
Return-1;
}
Flag = 1;
While (FLAG)
{
Printf ("Please input the Comand:/N ");

Scanf ("% C", & command );
Getchar ();

Switch (command)
{
Case 'r ':
Printf ("this modal isn' t commp leted! /N ");
Break;
Case 'I':/* invite */
I = exosip_call_build_initial_invite (& invite, dest_call, source_call, null, "This si a call for a conversation ");
If (I! = 0)
{
Printf ("intial invite failed! /N ");
Break;
}
// In SDP format, property A is a custom format, that is, it can store its own information, but it can only be two columns, such as account information
// However, It is tested that the format is "V o t" and the cause is unknown. It is estimated that the protocol stack needs to be checked during transmission.
Snprintf (TMP, 4096,
"V = 0/R/N"
"O = anonymous 0 0 in ip4 0.0.0.0/R/N"
"T = 1 10/R/N"
"A = Username: rainfish/R/N"
"A = password: 123/R/N ");
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 ();
Flag1 = 1;
While (flag1)
{
Je = exossip_event_wait (0,200 );

If (JE = NULL)
{
Printf ("no response or the time is over! /N ");
Break;
}

Switch (Je-> type)
{
Case exosip_call_invite:
Printf ("A New invite reveived! /N ");
Break;
Case exosip_call_proceeding:
Printf ("proceeding! /N ");
Break;
Case exosip_call_ringing:
Printf ("ringing! /N ");
// Call_id = Je-> CID;
// Dialog_id = Je-> did;
Printf ("call_id is % d, dialog_id is % d/N", je-> CID, je-> did );
Break;
Case exosip_call_answered:
Printf ("OK! Connected! /N ");
Call_id = Je-> CID;
Dialog_id = Je-> did;
Printf ("call_id is % d, dialog_id is % d/N", je-> CID, je-> did );

Exosip_call_build_ack (Je-> did, & ACK );
Exosip_call_send_ack (Je-> did, ACK );
Flag1 = 0;
Break;
Case exosip_call_closed:
Printf ("the other Sid closed! /N ");
Break;
Case exosip_call_ack:
Printf ("Ack received! /N ");
Break;
Default:
Printf ("other response! /N ");
Break;
}
Exosip_event_free (JE );

}
Break;
Case 'H ':
Printf ("holded! /N ");

Exosip_lock ();
Exosip_call_terminate (call_id, dialog_id );
Exosip_unlock ();
Break;
Case 'C ':
Printf ("this modal isn' t commp leted! /N ");
Break;
Case's ':
// Transfer info Method
Exosip_call_build_info (dialog_id, & info );
Snprintf (TMP, 4096,
"Hello, rainfish ");
Osip_message_set_body (Info, TMP, strlen (TMP ));
// The format can be set as needed. Text/plain indicates text information.
Osip_message_set_content_type (Info, "text/plain ");
Exosip_call_send_request (dialog_id, Info );
Break;
Case 'M ':
// Message transmission method, that is, instant message. Compared with the info method, I think the main difference is that messages do not need to be connected and information is transmitted directly, whereas info must
// Transmit data based on invite.
Printf ("The mothed: Message/N ");
Exosip_message_build_request (& message, "message", dest_call, source_call, null );
Snprintf (TMP, 4096,
"Hellor rainfish ");
Osip_message_set_body (message, TMP, strlen (TMP ));
// Assume the format is XML.
Osip_message_set_content_type (message, "text/XML ");
Exosip_message_send_request (Message );
Break;
Case 'q ':
Exosip_quit ();
Printf ("exit the setup! /N ");
Flag = 0;
Break;
}
}
Return (0 );
}






 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.