⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 siprtp.c

📁 基于sip协议的网络电话源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Bytes */	MIN_(min_stat.rx.bytes, audio->rtcp.stat.rx.bytes);	MAX_(max_stat.rx.bytes, audio->rtcp.stat.rx.bytes);	AVG_(avg_stat.rx.bytes, audio->rtcp.stat.rx.bytes);	/* Packet loss */	MIN_(min_stat.rx.loss, audio->rtcp.stat.rx.loss);	MAX_(max_stat.rx.loss, audio->rtcp.stat.rx.loss);	AVG_(avg_stat.rx.loss, audio->rtcp.stat.rx.loss);	/* Packet dup */	MIN_(min_stat.rx.dup, audio->rtcp.stat.rx.dup);	MAX_(max_stat.rx.dup, audio->rtcp.stat.rx.dup);	AVG_(avg_stat.rx.dup, audio->rtcp.stat.rx.dup);	/* Packet reorder */	MIN_(min_stat.rx.reorder, audio->rtcp.stat.rx.reorder);	MAX_(max_stat.rx.reorder, audio->rtcp.stat.rx.reorder);	AVG_(avg_stat.rx.reorder, audio->rtcp.stat.rx.reorder);	/* Jitter  */	MIN_(min_stat.rx.jitter.min, audio->rtcp.stat.rx.jitter.min);	MAX_(max_stat.rx.jitter.max, audio->rtcp.stat.rx.jitter.max);	AVG_(avg_stat.rx.jitter.avg, audio->rtcp.stat.rx.jitter.avg);	/* TX Statistisc: */	/* Packets */	MIN_(min_stat.tx.pkt, audio->rtcp.stat.tx.pkt);	MAX_(max_stat.tx.pkt, audio->rtcp.stat.tx.pkt);	AVG_(avg_stat.tx.pkt, audio->rtcp.stat.tx.pkt);	/* Bytes */	MIN_(min_stat.tx.bytes, audio->rtcp.stat.tx.bytes);	MAX_(max_stat.tx.bytes, audio->rtcp.stat.tx.bytes);	AVG_(avg_stat.tx.bytes, audio->rtcp.stat.tx.bytes);	/* Packet loss */	MIN_(min_stat.tx.loss, audio->rtcp.stat.tx.loss);	MAX_(max_stat.tx.loss, audio->rtcp.stat.tx.loss);	AVG_(avg_stat.tx.loss, audio->rtcp.stat.tx.loss);	/* Packet dup */	MIN_(min_stat.tx.dup, audio->rtcp.stat.tx.dup);	MAX_(max_stat.tx.dup, audio->rtcp.stat.tx.dup);	AVG_(avg_stat.tx.dup, audio->rtcp.stat.tx.dup);	/* Packet reorder */	MIN_(min_stat.tx.reorder, audio->rtcp.stat.tx.reorder);	MAX_(max_stat.tx.reorder, audio->rtcp.stat.tx.reorder);	AVG_(avg_stat.tx.reorder, audio->rtcp.stat.tx.reorder);	/* Jitter  */	MIN_(min_stat.tx.jitter.min, audio->rtcp.stat.tx.jitter.min);	MAX_(max_stat.tx.jitter.max, audio->rtcp.stat.tx.jitter.max);	AVG_(avg_stat.tx.jitter.avg, audio->rtcp.stat.tx.jitter.avg);	/* RTT */	MIN_(min_stat.rtt.min, audio->rtcp.stat.rtt.min);	MAX_(max_stat.rtt.max, audio->rtcp.stat.rtt.max);	AVG_(avg_stat.rtt.avg, audio->rtcp.stat.rtt.avg);	++count;    }    if (count == 0) {	puts("No active calls");	return;    }    printf("Total %d call(s) active.\n"	   "                    Average Statistics\n"	   "                    min     avg     max \n"	   "                -----------------------\n"	   " call duration: %7d %7d %7d %s\n"	   " connect delay: %7d %7d %7d %s\n"	   " RX stat:\n"	   "       packets: %7s %7s %7s %s\n"	   "       payload: %7s %7s %7s %s\n"	   "          loss: %7d %7d %7d %s\n"	   "  percent loss: %7.3f %7.3f %7.3f %s\n"	   "           dup: %7d %7d %7d %s\n"	   "       reorder: %7d %7d %7d %s\n"	   "        jitter: %7.3f %7.3f %7.3f %s\n"	   " TX stat:\n"	   "       packets: %7s %7s %7s %s\n"	   "       payload: %7s %7s %7s %s\n"	   "          loss: %7d %7d %7d %s\n"	   "  percent loss: %7.3f %7.3f %7.3f %s\n"	   "           dup: %7d %7d %7d %s\n"	   "       reorder: %7d %7d %7d %s\n"	   "        jitter: %7.3f %7.3f %7.3f %s\n"	   " RTT          : %7.3f %7.3f %7.3f %s\n"	   ,	   count,	   call_dur.min/1000, call_dur.avg/1000, call_dur.max/1000, 	   "seconds",	   call_pdd.min, call_pdd.avg, call_pdd.max, 	   "ms",	   /* rx */	   good_number(srx_min, min_stat.rx.pkt),	   good_number(srx_avg, avg_stat.rx.pkt),	   good_number(srx_max, max_stat.rx.pkt),	   "packets",	   good_number(brx_min, min_stat.rx.bytes),	   good_number(brx_avg, avg_stat.rx.bytes),	   good_number(brx_max, max_stat.rx.bytes),	   "bytes",	   min_stat.rx.loss, avg_stat.rx.loss, max_stat.rx.loss,	   "packets",	   	   min_stat.rx.loss*100.0/(min_stat.rx.pkt+min_stat.rx.loss),	   avg_stat.rx.loss*100.0/(avg_stat.rx.pkt+avg_stat.rx.loss),	   max_stat.rx.loss*100.0/(max_stat.rx.pkt+max_stat.rx.loss),	   "%",	   min_stat.rx.dup, avg_stat.rx.dup, max_stat.rx.dup,	   "packets",	   min_stat.rx.reorder, avg_stat.rx.reorder, max_stat.rx.reorder,	   "packets",	   min_stat.rx.jitter.min/1000.0, 	   avg_stat.rx.jitter.avg/1000.0, 	   max_stat.rx.jitter.max/1000.0,	   "ms",		   /* tx */	   good_number(stx_min, min_stat.tx.pkt),	   good_number(stx_avg, avg_stat.tx.pkt),	   good_number(stx_max, max_stat.tx.pkt),	   "packets",	   good_number(btx_min, min_stat.tx.bytes),	   good_number(btx_avg, avg_stat.tx.bytes),	   good_number(btx_max, max_stat.tx.bytes),	   "bytes",	   min_stat.tx.loss, avg_stat.tx.loss, max_stat.tx.loss,	   "packets",	   	   min_stat.tx.loss*100.0/(min_stat.tx.pkt+min_stat.tx.loss),	   avg_stat.tx.loss*100.0/(avg_stat.tx.pkt+avg_stat.tx.loss),	   max_stat.tx.loss*100.0/(max_stat.tx.pkt+max_stat.tx.loss),	   "%",	   min_stat.tx.dup, avg_stat.tx.dup, max_stat.tx.dup,	   "packets",	   min_stat.tx.reorder, avg_stat.tx.reorder, max_stat.tx.reorder,	   "packets",	   min_stat.tx.jitter.min/1000.0, 	   avg_stat.tx.jitter.avg/1000.0, 	   max_stat.tx.jitter.max/1000.0,	   "ms",	   /* rtt */	   min_stat.rtt.min/1000.0, 	   avg_stat.rtt.avg/1000.0, 	   max_stat.rtt.max/1000.0,	   "ms"	   );}#include "siprtp_report.c"static void list_calls(){    unsigned i;    puts("List all calls:");    for (i=0; i<app.max_calls; ++i) {	if (!app.call[i].inv)	    continue;	print_call(i);    }}static void hangup_call(unsigned index){    pjsip_tx_data *tdata;    pj_status_t status;    if (app.call[index].inv == NULL)	return;    status = pjsip_inv_end_session(app.call[index].inv, 603, NULL, &tdata);    if (status==PJ_SUCCESS && tdata!=NULL)	pjsip_inv_send_msg(app.call[index].inv, tdata);}static void hangup_all_calls(){    unsigned i;    for (i=0; i<app.max_calls; ++i) {	if (!app.call[i].inv)	    continue;	hangup_call(i);    }        /* Wait until all calls are terminated */    for (i=0; i<app.max_calls; ++i) {	while (app.call[i].inv)	    pj_thread_sleep(10);    }}static pj_bool_t simple_input(const char *title, char *buf, pj_size_t len){    char *p;    printf("%s (empty to cancel): ", title); fflush(stdout);    fgets(buf, len, stdin);    /* Remove trailing newlines. */    for (p=buf; ; ++p) {	if (*p=='\r' || *p=='\n') *p='\0';	else if (!*p) break;    }    if (!*buf)	return PJ_FALSE;        return PJ_TRUE;}static const char *MENU ="\n""Enter menu character:\n""  s    Summary\n""  l    List all calls\n""  h    Hangup a call\n""  H    Hangup all calls\n""  q    Quit\n""\n";/* Main screen menu */static void console_main(){    char input1[10];    unsigned i;    printf("%s", MENU);    for (;;) {	printf(">>> "); fflush(stdout);	fgets(input1, sizeof(input1), stdin);	switch (input1[0]) {	case 's':	    print_avg_stat();	    break;	case 'l':	    list_calls();	    break;	case 'h':	    if (!simple_input("Call number to hangup", input1, sizeof(input1)))		break;	    i = atoi(input1);	    hangup_call(i);	    break;	case 'H':	    hangup_all_calls();	    break;	case 'q':	    goto on_exit;	default:	    puts("Invalid command");	    printf("%s", MENU);	    break;	}	fflush(stdout);    }on_exit:    hangup_all_calls();}/***************************************************************************** * Below is a simple module to log all incoming and outgoing SIP messages *//* Notification on incoming messages */static pj_bool_t logger_on_rx_msg(pjsip_rx_data *rdata){    PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s:%d:\n"			 "%s\n"			 "--end msg--",			 rdata->msg_info.len,			 pjsip_rx_data_get_info(rdata),			 rdata->pkt_info.src_name,			 rdata->pkt_info.src_port,			 rdata->msg_info.msg_buf));        /* Always return false, otherwise messages will not get processed! */    return PJ_FALSE;}/* Notification on outgoing messages */static pj_status_t logger_on_tx_msg(pjsip_tx_data *tdata){        /* Important note:     *	tp_info field is only valid after outgoing messages has passed     *	transport layer. So don't try to access tp_info when the module     *	has lower priority than transport layer.     */    PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s:%d:\n"			 "%s\n"			 "--end msg--",			 (tdata->buf.cur - tdata->buf.start),			 pjsip_tx_data_get_info(tdata),			 tdata->tp_info.dst_name,			 tdata->tp_info.dst_port,			 tdata->buf.start));    /* Always return success, otherwise message will not get sent! */    return PJ_SUCCESS;}/* The module instance. */static pjsip_module msg_logger = {    NULL, NULL,				/* prev, next.		*/    { "mod-siprtp-log", 14 },		/* Name.		*/    -1,					/* Id			*/    PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority	        */    NULL,				/* load()		*/    NULL,				/* start()		*/    NULL,				/* stop()		*/    NULL,				/* unload()		*/    &logger_on_rx_msg,			/* on_rx_request()	*/    &logger_on_rx_msg,			/* on_rx_response()	*/    &logger_on_tx_msg,			/* on_tx_request.	*/    &logger_on_tx_msg,			/* on_tx_response()	*/    NULL,				/* on_tsx_state()	*/};/***************************************************************************** * Console application custom logging: */static FILE *log_file;static void app_log_writer(int level, const char *buffer, int len){    /* Write to both stdout and file. */    if (level <= app.app_log_level)	pj_log_write(level, buffer, len);    if (log_file) {	fwrite(buffer, len, 1, log_file);	fflush(log_file);    }}pj_status_t app_logging_init(void){    /* Redirect log function to ours */    pj_log_set_log_func( &app_log_writer );    /* If output log file is desired, create the file: */    if (app.log_filename) {	log_file = fopen(app.log_filename, "wt");	if (log_file == NULL) {	    PJ_LOG(1,(THIS_FILE, "Unable to open log file %s", 		      app.log_filename));   	    return -1;	}    }    return PJ_SUCCESS;}void app_logging_shutdown(void){    /* Close logging file, if any: */    if (log_file) {	fclose(log_file);	log_file = NULL;    }}/* * main() */int main(int argc, char *argv[]){    unsigned i;    pj_status_t status;    /* Must init PJLIB first */    status = pj_init();    if (status != PJ_SUCCESS)	return 1;    /* Get command line options */    status = init_options(argc, argv);    if (status != PJ_SUCCESS)	return 1;    /* Verify options: */    /* Auto-quit can not be specified for UAS */    if (app.auto_quit && app.uri_to_call.slen == 0) {	printf("Error: --auto-quit option only valid for outgoing "	       "mode (UAC) only\n");	return 1;    }    /* Init logging */    status = app_logging_init();    if (status != PJ_SUCCESS)	return 1;    /* Init SIP etc */    status = init_sip();    if (status != PJ_SUCCESS) {	app_perror(THIS_FILE, "Initialization has failed", status);	destroy_sip();	return 1;    }    /* Register module to log incoming/outgoing messages */    pjsip_endpt_register_module(app.sip_endpt, &msg_logger);    /* Init media */    status = init_media();    if (status != PJ_SUCCESS) {	app_perror(THIS_FILE, "Media initialization failed", status);	destroy_sip();	return 1;    }    /* Start worker threads */    for (i=0; i<app.thread_count; ++i) {	pj_thread_create( app.pool, "app", &sip_worker_thread, NULL,			  0, 0, &app.sip_thread[i]);    }    /* If URL is specified, then make call immediately */    if (app.uri_to_call.slen) {	unsigned i;	PJ_LOG(3,(THIS_FILE, "Making %d calls to %s..", app.max_calls,		  app.uri_to_call.ptr));	for (i=0; i<app.max_calls; ++i) {	    status = make_call(&app.uri_to_call);	    if (status != PJ_SUCCESS) {		app_perror(THIS_FILE, "Error making call", status);		break;	    }	}	if (app.auto_quit) {	    /* Wait for calls to complete */	    while (app.uac_calls < app.max_calls)		pj_thread_sleep(100);	    pj_thread_sleep(200);	} else {	    /* Start user interface loop */	    console_main();	}    } else {	PJ_LOG(3,(THIS_FILE, "Ready for incoming calls (max=%d)", 		  app.max_calls));	/* Start user interface loop */	console_main();    }        /* Shutting down... */    destroy_sip();    destroy_media();    if (app.pool) {	pj_pool_release(app.pool);	app.pool = NULL;	pj_caching_pool_destroy(&app.cp);    }    app_logging_shutdown();    /* Shutdown PJLIB */    pj_shutdown();    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -