📄 sipua.c
字号:
sip_status_t sip_rc;
sip_msg_error_t error;
sip_msg_body_t * sdp_body = 0;
sdp_announcement_t * sdp;
char hostname[50];
gethostname(hostname, 50);
calling_uri = sip_msg_new_sip_url("user",
hostname,
port,
NULL,
NULL,
SIP_MSG_NONE,
NULL,
-1,
NULL,
SIP_FALSE,
NULL,
NULL);
if(!calling_uri) {
sip_call_delete_instance(sip_ch_inst);
printf("Unable to build the calling uri");
return(1);
}
if(interactive) {
printf("Press enter to start the call...\n");
getchar();
}
from = sip_msg_new_from_header(calling_uri, NULL, NULL, NULL, NULL);
if(!from) {
printf("Unable to build the From: header\n");
return(1);
}
contact = sip_msg_new_contact_header(calling_uri, NULL, -1, -1, NULL, NULL);
if(!contact) {
sip_call_delete_instance(sip_ch_inst);
printf("Unable to build the Contact: header\n");
return(1);
}
request_uri = sip_msg_parse_uri(sip_called_uri, &error);
if(!request_uri) {
printf("Syntax error near token '%s' in request URI\n",
error.unexpected_token);
return(1);
}
to = sip_msg_new_to_header(request_uri, NULL, NULL, NULL, NULL);
if(!to) {
printf("Unable to build the To: header\n");
return(1);
}
call = SIP_CALL_NO_CALL;
dialog = SIP_CALL_NO_DIALOG;
transaction = SIP_CALL_NO_TRANSACTION;
if(do_body) {
sdp = sdp_new_announcement(0,
"media",
"user1",
"12341234",
"2",
"IN",
"IP4",
"127.0.0.2",
NULL);
if(!sdp) {
printf("Unable to build SDP announcement\n");
exit(1);
}
sdp_body = sip_msg_new_sdp_body(sdp,
SIP_FALSE, NULL);
}
if(!subscribe_event_name) {
/* Normal INVITE case */
sip_rc = sip_call_initiate(sip_ch_inst,
&call,
&dialog,
&transaction,
request_uri,
from,
to,
contact,
NULL,
sdp_body,
NULL);
if(sip_rc != SIP_NORMAL) {
printf("Error %d returned from sip_call_initiate\n", sip_rc);
return(1);
} else {
printf("Initiate call ongoing...\n");
}
} else {
/* SUBSCRIBE case */
sip_msg_header_t * event;
sip_subs_t subscription_id;
event = sip_msg_new_event_header
(subscribe_event_name, NULL, NULL, NULL);
if(!event) {
printf("Error returned from sip_msg_new_event_header\n");
return 1;
}
sip_rc = sip_call_evt_subscribe
(sip_ch_inst,
&call,
&dialog,
&transaction,
&subscription_id,
request_uri,
from,
to,
contact,
event,
NULL, /* expires header */
NULL,
sdp_body,
NULL);
if(sip_rc != SIP_NORMAL) {
printf("Error %d returned from sip_call_evt_subscribe\n", sip_rc);
return(1);
} else {
printf("SUBSCRIBE sent...\n");
}
}
sip_msg_free_uri(calling_uri);
sip_msg_free_uri(request_uri);
sip_msg_free_header(from);
sip_msg_free_header(to);
sip_msg_free_header(contact);
if(do_body) {
sip_msg_free_body(sdp_body);
}
if(cancel_delay) {
sip_trans_t new_trans;
sleep(cancel_delay);
printf("Releasing the call with a CANCEL or a BYE\n");
/* send a CANCEL request */
sip_call_release(sip_ch_inst,
call,
dialog,
&new_trans,
NULL,
NULL,
SIP_CALL_RELEASE_AUTOMATIC,
NULL);
}
return(0);
}
/*
* FACILITY:
*
* usage
*
* ABSTRACT:
*
* The help string displayed in case of error when
* parsing the comand line.
*
* FORMAL PARAMETERS:
*
* The name of the command (argv[0]).
*
* RETURN VALUE:
*
* None
*
*/
void usage(char * command_name, char * local_ip)
{
printf("\n%s [-c request_URI]"
"\n"
"\n Starts a SIP UAS on the specified port, and an optional UAC"
"\n initiating a call (with the -c option)."
"\n"
"\n -p port : The -p option specifies the UDP port number"
"\n for the proxy server. The default port is 5060."
"\n"
"\n -c Req_URI : The -c option sends an INVITE request"
"\n to the specified URI, and manage the call"
"\n as a UAC. You can use the URI syntax to"
"\n set the destination port number (e.g."
"\n sip:user@%s:6060). 3 seconds after"
"\n call establishment, this option sends a"
"\n BYE request to terminate the call."
"\n"
"\n -cc delay : Modifier for the -c option. This option"
"\n sends a CANCEL request 'delay' seconds after"
"\n the INVITE request, if and only if a 1xx"
"\n response has been recieved."
"\n"
"\n -cb : Modifier for the -c option. This option"
"\n remove the BYE transaction after call"
"\n establishment. The call is leaved opened"
"\n once established."
"\n"
"\n -cs event : Modifier for the -c option. Sends a SUBSCRIBE"
"\n request (with the given event name) instead the"
"\n normal INVITE request."
"\n"
"\n -us nb : Modifier for the -cs option: Unsubscribe after"
"\n nb NOTIFY have been reveived."
"\n"
"\n -b delay : When UAS, send a BYE 'delay' seconds after"
"\n call establishment."
"\n"
"\n -d delay : When UAS, wait for 'delay' seconds before"
"\n answering an INVITE request."
"\n"
"\n -nd : When UAS, do not wait before accepting calls."
"\n"
"\n -ne : Do not exit when the first call is finished."
"\n"
"\n -i : Interactive mode."
"\n"
"\n -h : Displays this help screen."
"\n"
"\n -bd : Insert fake SDP body in INVITE request."
"\n"
"\n",
command_name,
local_ip);
}
/*
* FACILITY:
*
* main
*
* ABSTRACT:
*
* The main entry of the process
*
* FORMAL PARAMETERS:
*
* argc, argv command line parameters
*
* RETURN VALUE:
*
* None
*
*/
int main(int argc, char *argv[])
{
sip_status_t sip_status = SIP_NORMAL;
sip_trp_info_t sip_trp_info[1];
sip_uint32_t sip_nb_trp = 1;
sip_call_callback_vector_t sip_ch_callback;
sip_call_inst_t sip_ch_inst;
sip_uint32_t sip_remaining_indic = 0;
struct hostent * sip_local_host = NULL;
char hostname[80] = { 0 };
int sip_port = 5060;
char * sip_called_uri = NULL;
char sip_local_ip[50];
char sip_pid[16] = { 0 };
sip_bool_t do_body = SIP_FALSE;
sigset_t sig_set;
int argi;
/* Mask the SIPPIPE signal */
sigemptyset(&sig_set);
sigaddset(&sig_set, SIGPIPE);
pthread_sigmask( SIG_BLOCK, &sig_set, 0 );
if ((gethostname(hostname,64) != 0)
|| (!(sip_local_host = gethostbyname(hostname))))
{
printf("cannot get local host informations\n");
exit(1);
}
strcpy(sip_local_ip,
(char *) inet_ntoa
(*(struct in_addr *)(sip_local_host->h_addr_list[0])));
for(argi = 1; argi < argc; argi++) {
if(!strcmp(argv[argi], "-p")) {
if((++argi) < argc) {
sip_port = atol(argv[argi]);
} else {
usage(argv[0],sip_local_ip);
exit(1);
}
}
if((!strcmp(argv[argi], "-h" )) ||
(!strcmp(argv[argi], "--h" )) ||
(!strcmp(argv[argi], "--help")) ||
(!strcmp(argv[argi], "-help" )) ) {
usage(argv[0],sip_local_ip);
exit(0);
}
if(!strcmp(argv[argi], "-i")) {
interactive = SIP_TRUE;
}
if(!strcmp(argv[argi], "-bd")) {
do_body = SIP_TRUE;
}
if(!strcmp(argv[argi], "-cb")) {
no_bye = SIP_TRUE;
}
if(!strcmp(argv[argi], "-nd")) {
no_delay = SIP_TRUE;
}
if(!strcmp(argv[argi], "-ne")) {
auto_exit = SIP_FALSE;
}
if(!strcmp(argv[argi], "-c")) {
if((++argi) < argc) {
sip_called_uri = argv[argi];
} else {
usage(argv[0],sip_local_ip);
exit(1);
}
}
if(!strcmp(argv[argi], "-cc")) {
if((++argi) < argc) {
cancel_delay = atol(argv[argi]);
} else {
usage(argv[0],sip_local_ip);
exit(1);
}
}
if(!strcmp(argv[argi], "-cs")) {
if((++argi) < argc) {
subscribe_event_name = argv[argi];
} else {
usage(argv[0],sip_local_ip);
exit(1);
}
}
if(!strcmp(argv[argi], "-b")) {
if((++argi) < argc) {
uas_bye_delay = atol(argv[argi]);
} else {
usage(argv[0],sip_local_ip);
exit(1);
}
}
if(!strcmp(argv[argi], "-us")) {
if((++argi) < argc) {
unscuscribe_counter = atol(argv[argi]);
} else {
usage(argv[0],sip_local_ip);
exit(1);
}
}
if(!strcmp(argv[argi], "-d")) {
if((++argi) < argc) {
uas_invite_delay = atol(argv[argi]);
} else {
usage(argv[0],sip_local_ip);
exit(1);
}
}
}
strcat(hostname,"_sipua_");
sprintf(sip_pid,"%d",getpid());
strcat(hostname,sip_pid);
sip_status = sip_init_lib(hostname,
0,
NULL,
SIP_API_VERSION);
printf("SIP User-Agent (%s) IP:%s started using UDP port %d\n",
hostname,
sip_local_ip,
sip_port);
/* Fill the SIP Call-Handling callback vector */
memset(&sip_ch_callback, 0, sizeof(sip_call_callback_vector_t));
sip_ch_callback.sip_call_on_initiate = sip_call_on_initiate;
sip_ch_callback.sip_call_on_connect = sip_call_on_connect;
sip_ch_callback.sip_call_on_release = sip_call_on_release;
sip_ch_callback.sip_call_on_cancel = sip_call_on_cancel;
sip_ch_callback.sip_call_on_progress = sip_call_on_progress;
sip_ch_callback.sip_call_on_accept = sip_call_on_accept;
sip_ch_callback.sip_call_on_get_media = sip_call_on_get_media;
sip_ch_callback.sip_call_on_request = sip_call_on_request;
sip_ch_callback.sip_call_on_reply = sip_call_on_reply;
sip_ch_callback.sip_call_on_event = sip_call_on_event;
sip_ch_callback.sip_call_on_evt_subscribe = sip_call_on_evt_subscribe;
sip_ch_callback.sip_call_on_evt_notify = sip_call_on_evt_notify;
/* Fill the transport info array */
sip_trp_info[0].trp_name = strdup("my_address");
sip_trp_info[0].dns_name = NULL;
sip_trp_info[0].address = sip_local_ip;
sip_trp_info[0].port = sip_port;
sip_trp_info[0].trp_type = SIP_TRP_UDP;
/* Create the SIP transaction instance */
sip_status = sip_call_create_instance(&sip_ch_inst,
hostname,
SIP_CALL_ENTITY_UA,
&sip_ch_callback,
sip_trp_info,
sip_nb_trp,
NULL,
NULL);
if (sip_status != SIP_NORMAL)
{
printf("Error in sip_call_create_instance function: %d\n", sip_status);
exit(1);
}
/* Enable the SIP transaction instance */
sip_status = sip_call_enable_instance(sip_ch_inst);
if (sip_status != SIP_NORMAL)
{
printf("Error in sip_call_enable_instance function: %d\n", sip_status);
exit(1);
}
if ((sip_called_uri)
&& (call_uri(sip_called_uri,
sip_ch_inst,
sip_port,
do_body)))
{
sip_call_delete_instance(sip_ch_inst);
exit(1);
}
/* Waiting for incoming messages */
while (1)
{
sip_status = sip_call_deliver_indic(sip_ch_inst,
SIP_FALSE, /* non blocking */
SIP_DELIVER_ALL_MSG,
&sip_remaining_indic);
if (sip_status != SIP_NORMAL)
{
sip_call_delete_instance(sip_ch_inst);
printf("Error %d in delivering indication\n", sip_status);
exit(1);
}
if (sip_exit && auto_exit)
{
sleep(1);
if(interactive) {
printf("Press enter to exit...\n");
getchar();
}
sip_call_delete_instance(sip_ch_inst);
// printf("Exiting\n");
exit(0);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -