[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