[asterisk-commits] mnicholson: branch group/res_fax r240407 - /team/group/res_fax/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jan 15 14:04:33 CST 2010


Author: mnicholson
Date: Fri Jan 15 14:04:29 2010
New Revision: 240407

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=240407
Log:
Added stats tracking and reporting to res_fax_spandsp.

Modified:
    team/group/res_fax/res/res_fax_spandsp.c

Modified: team/group/res_fax/res/res_fax_spandsp.c
URL: http://svnview.digium.com/svn/asterisk/team/group/res_fax/res/res_fax_spandsp.c?view=diff&rev=240407&r1=240406&r2=240407
==============================================================================
--- team/group/res_fax/res/res_fax_spandsp.c (original)
+++ team/group/res_fax/res/res_fax_spandsp.c Fri Jan 15 14:04:29 2010
@@ -106,6 +106,28 @@
 	.cli_show_stats = spandsp_fax_cli_show_stats,
 };
 
+struct spandsp_fax_stats {
+	int success;
+	int nofax;
+	int neg_failed;
+	int failed_to_train;
+	int rx_protocol_error;
+	int tx_protocol_error;
+	int protocol_error;
+	int retries_exceeded;
+	int file_error;
+	int mem_error;
+	int call_dropped;
+	int unknown_error;
+	int switched;
+};
+
+static struct {
+	ast_mutex_t lock;
+	struct spandsp_fax_stats g711;
+	struct spandsp_fax_stats t38;
+} spandsp_global_stats;
+
 struct spandsp_pvt {
 	struct ast_fax_session *session;  /* XXX this is unnecessary */
 	unsigned int ist38:1;
@@ -115,6 +137,8 @@
 	t30_state_t *t30_state;
 	t38_core_state_t *t38_core_state;
 
+	struct spandsp_fax_stats *stats;
+
 	struct ast_timer *timer;
 	AST_LIST_HEAD(frame_queue, ast_frame) read_frames;
 };
@@ -123,6 +147,7 @@
 static int t38_tx_packet_handler(t38_core_state_t *t38_core_state, void *data, const uint8_t *buf, int len, int count);
 static void t30_phase_e_handler(t30_state_t *t30_state, void *data, int completion_code);
 static void spandsp_log(int level, const char *msg);
+static int update_stats(struct spandsp_pvt *p, int completion_code);
 
 static void set_logging(logging_state_t *state);
 static void set_local_info(t30_state_t *t30_state, struct ast_fax_session_details *details);
@@ -176,6 +201,119 @@
 	return 0;
 }
 
+static int update_stats(struct spandsp_pvt *p, int completion_code)
+{
+	switch (completion_code) {
+	case T30_ERR_OK:
+		ast_atomic_fetchadd_int(&p->stats->success, 1);
+		break;
+
+	/* Link problems */
+	case T30_ERR_CEDTONE:            /*! The CED tone exceeded 5s */
+	case T30_ERR_T0_EXPIRED:         /*! Timed out waiting for initial communication */
+	case T30_ERR_T1_EXPIRED:         /*! Timed out waiting for the first message */
+	case T30_ERR_T3_EXPIRED:         /*! Timed out waiting for procedural interrupt */
+	case T30_ERR_HDLC_CARRIER:       /*! The HDLC carrier did not stop in a timely manner */
+	case T30_ERR_CANNOT_TRAIN:       /*! Failed to train with any of the compatible modems */
+		ast_atomic_fetchadd_int(&p->stats->failed_to_train, 1);
+		break;
+
+	case T30_ERR_OPER_INT_FAIL:      /*! Operator intervention failed */
+	case T30_ERR_INCOMPATIBLE:       /*! Far end is not compatible */
+	case T30_ERR_RX_INCAPABLE:       /*! Far end is not able to receive */
+	case T30_ERR_TX_INCAPABLE:       /*! Far end is not able to transmit */
+	case T30_ERR_NORESSUPPORT:       /*! Far end cannot receive at the resolution of the image */
+	case T30_ERR_NOSIZESUPPORT:      /*! Far end cannot receive at the size of image */
+		ast_atomic_fetchadd_int(&p->stats->neg_failed, 1);
+		break;
+
+	case T30_ERR_UNEXPECTED:         /*! Unexpected message received */
+		ast_atomic_fetchadd_int(&p->stats->protocol_error, 1);
+		break;
+
+	/* Phase E status values returned to a transmitter */
+	case T30_ERR_TX_BADDCS:          /*! Received bad response to DCS or training */
+	case T30_ERR_TX_BADPG:           /*! Received a DCN from remote after sending a page */
+	case T30_ERR_TX_ECMPHD:          /*! Invalid ECM response received from receiver */
+	case T30_ERR_TX_GOTDCN:          /*! Received a DCN while waiting for a DIS */
+	case T30_ERR_TX_INVALRSP:        /*! Invalid response after sending a page */
+	case T30_ERR_TX_NODIS:           /*! Received other than DIS while waiting for DIS */
+	case T30_ERR_TX_PHBDEAD:         /*! Received no response to DCS, training or TCF */
+	case T30_ERR_TX_PHDDEAD:         /*! No response after sending a page */
+	case T30_ERR_TX_T5EXP:           /*! Timed out waiting for receiver ready (ECM mode) */
+		ast_atomic_fetchadd_int(&p->stats->tx_protocol_error, 1);
+		break;
+
+	/* Phase E status values returned to a receiver */
+	case T30_ERR_RX_ECMPHD:          /*! Invalid ECM response received from transmitter */
+	case T30_ERR_RX_GOTDCS:          /*! DCS received while waiting for DTC */
+	case T30_ERR_RX_INVALCMD:        /*! Unexpected command after page received */
+	case T30_ERR_RX_NOCARRIER:       /*! Carrier lost during fax receive */
+	case T30_ERR_RX_NOEOL:           /*! Timed out while waiting for EOL (end Of line) */
+		ast_atomic_fetchadd_int(&p->stats->rx_protocol_error, 1);
+		break;
+	case T30_ERR_RX_NOFAX:           /*! Timed out while waiting for first line */
+		ast_atomic_fetchadd_int(&p->stats->nofax, 1);
+		break;
+	case T30_ERR_RX_T2EXPDCN:        /*! Timer T2 expired while waiting for DCN */
+	case T30_ERR_RX_T2EXPD:          /*! Timer T2 expired while waiting for phase D */
+	case T30_ERR_RX_T2EXPFAX:        /*! Timer T2 expired while waiting for fax page */
+	case T30_ERR_RX_T2EXPMPS:        /*! Timer T2 expired while waiting for next fax page */
+	case T30_ERR_RX_T2EXPRR:         /*! Timer T2 expired while waiting for RR command */
+	case T30_ERR_RX_T2EXP:           /*! Timer T2 expired while waiting for NSS, DCS or MCF */
+	case T30_ERR_RX_DCNWHY:          /*! Unexpected DCN while waiting for DCS or DIS */
+	case T30_ERR_RX_DCNDATA:         /*! Unexpected DCN while waiting for image data */
+	case T30_ERR_RX_DCNFAX:          /*! Unexpected DCN while waiting for EOM, EOP or MPS */
+	case T30_ERR_RX_DCNPHD:          /*! Unexpected DCN after EOM or MPS sequence */
+	case T30_ERR_RX_DCNRRD:          /*! Unexpected DCN after RR/RNR sequence */
+	case T30_ERR_RX_DCNNORTN:        /*! Unexpected DCN after requested retransmission */
+		ast_atomic_fetchadd_int(&p->stats->rx_protocol_error, 1);
+		break;
+
+	/* TIFF file problems */
+	case T30_ERR_FILEERROR:          /*! TIFF/F file cannot be opened */
+	case T30_ERR_NOPAGE:             /*! TIFF/F page not found */
+	case T30_ERR_BADTIFF:            /*! TIFF/F format is not compatible */
+	case T30_ERR_BADPAGE:            /*! TIFF/F page number tag missing */
+	case T30_ERR_BADTAG:             /*! Incorrect values for TIFF/F tags */
+	case T30_ERR_BADTIFFHDR:         /*! Bad TIFF/F header - incorrect values in fields */
+		ast_atomic_fetchadd_int(&p->stats->file_error, 1);
+		break;
+	case T30_ERR_NOMEM:              /*! Cannot allocate memory for more pages */
+		ast_atomic_fetchadd_int(&p->stats->mem_error, 1);
+		break;
+
+	/* General problems */
+	case T30_ERR_RETRYDCN:           /*! Disconnected after permitted retries */
+		ast_atomic_fetchadd_int(&p->stats->retries_exceeded, 1);
+		break;
+	case T30_ERR_CALLDROPPED:        /*! The call dropped prematurely */
+		ast_atomic_fetchadd_int(&p->stats->call_dropped, 1);
+		break;
+
+	/* Feature negotiation issues */
+	case T30_ERR_NOPOLL:             /*! Poll not accepted */
+	case T30_ERR_IDENT_UNACCEPTABLE: /*! Far end's ident is not acceptable */
+	case T30_ERR_SUB_UNACCEPTABLE:   /*! Far end's sub-address is not acceptable */
+	case T30_ERR_SEP_UNACCEPTABLE:   /*! Far end's selective polling address is not acceptable */
+	case T30_ERR_PSA_UNACCEPTABLE:   /*! Far end's polled sub-address is not acceptable */
+	case T30_ERR_SID_UNACCEPTABLE:   /*! Far end's sender identification is not acceptable */
+	case T30_ERR_PWD_UNACCEPTABLE:   /*! Far end's password is not acceptable */
+	case T30_ERR_TSA_UNACCEPTABLE:   /*! Far end's transmitting subscriber internet address is not acceptable */
+	case T30_ERR_IRA_UNACCEPTABLE:   /*! Far end's internet routing address is not acceptable */
+	case T30_ERR_CIA_UNACCEPTABLE:   /*! Far end's calling subscriber internet address is not acceptable */
+	case T30_ERR_ISP_UNACCEPTABLE:   /*! Far end's internet selective polling address is not acceptable */
+	case T30_ERR_CSA_UNACCEPTABLE:   /*! Far end's called subscriber internet address is not acceptable */
+		ast_atomic_fetchadd_int(&p->stats->neg_failed, 1);
+		break;
+	default:
+		ast_atomic_fetchadd_int(&p->stats->unknown_error, 1);
+		ast_log(LOG_WARNING, "unknown FAX session result '%d' (%s)\n", completion_code, t30_completion_code_to_str(completion_code));
+		return -1;
+	}
+	return 0;
+}
+
 /*! \brief Phase E handler callback.
  * \param t30_state the span t30 state
  * \param data this will be the ast_fax_session
@@ -195,6 +333,8 @@
 	ast_debug(5, "FAX session '%d' entering phase E\n", s->id);
 
 	p->isdone = 1;
+
+	update_stats(p, completion_code);
 
 	t30_get_transfer_statistics(t30_state, &stats);
 
@@ -314,10 +454,13 @@
 
 	s->fd = ast_timer_fd(p->timer);
 
+	p->stats = &spandsp_global_stats.g711;
+
 	if (s->details->caps & AST_FAX_TECH_T38) {
 		if ((s->details->caps & AST_FAX_TECH_AUDIO) == 0) {
 			/* audio mode was not requested, start in T.38 mode */
 			p->ist38 = 1;
+			p->stats = &spandsp_global_stats.t38;
 		}
 
 		/* init t38 stuff */
@@ -516,8 +659,10 @@
 	t30_terminate(p->t30_state);
 
 	s->details->option.switch_to_t38 = 1;
+	ast_atomic_fetchadd_int(&p->stats->switched, 1);
 
 	p->ist38 = 1;
+	p->stats = &spandsp_global_stats.t38;
 	spandsp_fax_start(s);
 
 	return 0;
@@ -569,6 +714,37 @@
 
 static char *spandsp_fax_cli_show_stats(int fd)
 {
+	ast_mutex_lock(&spandsp_global_stats.lock);
+	ast_cli(fd, "\n%-20.20s\n", "Spandsp G.711");
+	ast_cli(fd, "%-20.20s : %d\n", "Success", spandsp_global_stats.g711.success);
+	ast_cli(fd, "%-20.20s : %d\n", "Switched to T.38", spandsp_global_stats.g711.switched);
+	ast_cli(fd, "%-20.20s : %d\n", "Call Dropped", spandsp_global_stats.g711.call_dropped);
+	ast_cli(fd, "%-20.20s : %d\n", "No FAX", spandsp_global_stats.g711.nofax);
+	ast_cli(fd, "%-20.20s : %d\n", "Negotation Failed", spandsp_global_stats.g711.neg_failed);
+	ast_cli(fd, "%-20.20s : %d\n", "Train Failure", spandsp_global_stats.g711.failed_to_train);
+	ast_cli(fd, "%-20.20s : %d\n", "Retries Exceeded", spandsp_global_stats.g711.retries_exceeded);
+	ast_cli(fd, "%-20.20s : %d\n", "Protocol Error", spandsp_global_stats.g711.protocol_error);
+	ast_cli(fd, "%-20.20s : %d\n", "TX Protocol Error", spandsp_global_stats.g711.tx_protocol_error);
+	ast_cli(fd, "%-20.20s : %d\n", "RX Protocol Error", spandsp_global_stats.g711.rx_protocol_error);
+	ast_cli(fd, "%-20.20s : %d\n", "File Error", spandsp_global_stats.g711.file_error);
+	ast_cli(fd, "%-20.20s : %d\n", "Memory Error", spandsp_global_stats.g711.mem_error);
+	ast_cli(fd, "%-20.20s : %d\n", "Unknown Error", spandsp_global_stats.g711.unknown_error);
+
+	ast_cli(fd, "\n%-20.20s\n", "Spandsp T.38");
+	ast_cli(fd, "%-20.20s : %d\n", "Success", spandsp_global_stats.t38.success);
+	ast_cli(fd, "%-20.20s : %d\n", "Call Dropped", spandsp_global_stats.t38.call_dropped);
+	ast_cli(fd, "%-20.20s : %d\n", "No FAX", spandsp_global_stats.t38.nofax);
+	ast_cli(fd, "%-20.20s : %d\n", "Negotation Failed", spandsp_global_stats.t38.neg_failed);
+	ast_cli(fd, "%-20.20s : %d\n", "Train Failure", spandsp_global_stats.t38.failed_to_train);
+	ast_cli(fd, "%-20.20s : %d\n", "Retries Exceeded", spandsp_global_stats.t38.retries_exceeded);
+	ast_cli(fd, "%-20.20s : %d\n", "Protocol Error", spandsp_global_stats.t38.protocol_error);
+	ast_cli(fd, "%-20.20s : %d\n", "TX Protocol Error", spandsp_global_stats.t38.tx_protocol_error);
+	ast_cli(fd, "%-20.20s : %d\n", "RX Protocol Error", spandsp_global_stats.t38.rx_protocol_error);
+	ast_cli(fd, "%-20.20s : %d\n", "File Error", spandsp_global_stats.t38.file_error);
+	ast_cli(fd, "%-20.20s : %d\n", "Memory Error", spandsp_global_stats.t38.mem_error);
+	ast_cli(fd, "%-20.20s : %d\n", "Unknown Error", spandsp_global_stats.t38.unknown_error);
+	ast_mutex_unlock(&spandsp_global_stats.lock);
+
 	return CLI_SUCCESS;
 }
 
@@ -576,12 +752,14 @@
 static int unload_module(void)
 {
 	ast_fax_tech_unregister(&spandsp_fax_tech);
+	ast_mutex_destroy(&spandsp_global_stats.lock);
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 /*! \brief load res_fax_spandsp */
 static int load_module(void)
 {
+	ast_mutex_init(&spandsp_global_stats.lock);
 	spandsp_fax_tech.module = ast_module_info->self;
 	if (ast_fax_tech_register(&spandsp_fax_tech) < 0) {
 		ast_log(LOG_ERROR, "failed to register FAX technology\n");




More information about the asterisk-commits mailing list