示例#1
0
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
    int i;
    t30_stats_t t;
    char ident[21];
    
    i = (int) (intptr_t) user_data;
    printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
    t30_get_transfer_statistics(s, &t);
    printf("%c: Phase E: bit rate %d\n", i, t.bit_rate);
    printf("%c: Phase E: ECM %s\n", i, (t.error_correcting_mode)  ?  "on"  :  "off");
    printf("%c: Phase E: pages transferred %d\n", i, t.pages_transferred);
    printf("%c: Phase E: image size %d x %d\n", i, t.width, t.length);
    printf("%c: Phase E: image resolution %d x %d\n", i, t.x_resolution, t.y_resolution);
    printf("%c: Phase E: bad rows %d\n", i, t.bad_rows);
    printf("%c: Phase E: longest bad row run %d\n", i, t.longest_bad_row_run);
    printf("%c: Phase E: coding method %s\n", i, t4_encoding_to_str(t.encoding));
    printf("%c: Phase E: image size %d bytes\n", i, t.image_size);
    t30_get_local_ident(s, ident);
    printf("%c: Phase E: local ident '%s'\n", i, ident);
    t30_get_far_ident(s, ident);
    printf("%c: Phase E: remote ident '%s'\n", i, ident);
    succeeded[i - 'A'] = (result == T30_ERR_OK)  &&  (t.pages_transferred == 12);
    //done[i - 'A'] = TRUE;
}
示例#2
0
/*
 * T30 fax session consists of 5 phases:
 *
 *      1) Phase A "Call Establishment"
 *          Off-hook, Dialing, Ringing, Answering, CNG and CED Tones
 *
 *      2) Phase B "Pre-Message Procedure"
 *          Fax Terminal Identification, Capabilities exchanged and Set, Training
 *
 *      3) Phase C "In-Message Procedure, Message Transmission"
 *          Transmission of Pages, Line Supervision, Error Detection and Correction
 *
 *      4) Phase D "Post Message Procedure"
 *          End-of-Message Signaling, Page Confirmation
 *
 *      5) Phase E "Call Release"
 *          Call Disconnect and Return to On-hook State
 */
static int phase_b_handler(t30_state_t *s, void *user_data, int result)
{
	t30_stats_t t30_stats;

	const char *local_ident;
	const char *far_ident;
	const char *tmp;
	fax_session_t *f_session = (fax_session_t *)user_data;

	t30_get_transfer_statistics(s, &t30_stats);

	tmp = t30_get_tx_ident(s);
	local_ident = tmp ? tmp : "";
	tmp = t30_get_rx_ident(s);
	far_ident = tmp ? tmp : "";

	printf("fax: Phase B handler (Call: '%s' %s)\n", f_session->call_id,
		   f_session->pvt.caller ? "sender" : "receiver");
	printf("fax: === Negotiation Result =======================================================\n");
	printf("fax: Remote station id: %s\n", far_ident);
	printf("fax: Local station id:  %s\n", local_ident);
	printf("fax: Transfer Rate:     %i\n", t30_stats.bit_rate);

	printf("fax: ECM status        %s\n", (t30_stats.error_correcting_mode) ? "on" : "off");
	printf("fax: remote country:   %s\n", (t30_get_rx_country(s) ? (t30_get_rx_country(s)) : ""));
	printf("fax: remote vendor:    %s\n", (t30_get_rx_vendor(s) ? (t30_get_rx_vendor(s)) : ""));
	printf("fax: remote model:     %s\n", (t30_get_rx_model(s) ? (t30_get_rx_model(s)) : ""));

	printf("fax: ==============================================================================\n");

	return T30_ERR_OK;
}
示例#3
0
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
    int session;
    t30_stats_t t;
    const char *u;
    char ident[21];
    
    session = (intptr_t) user_data;
    printf("Phase E handler on session %d - (%d) %s\n", session, result, t30_completion_code_to_str(result));    
    t30_get_transfer_statistics(s, &t);
    printf( "Phase E: bit rate %d\n", t.bit_rate);
    printf( "Phase E: ECM %s\n", (t.error_correcting_mode)  ?  "on"  :  "off");
    printf( "Phase E: pages transferred %d\n", t.pages_transferred);
    printf( "Phase E: image size %d x %d\n", t.width, t.length);
    printf( "Phase E: image resolution %d x %d\n", t.x_resolution, t.y_resolution);
    printf( "Phase E: bad rows %d\n", t.bad_rows);
    printf( "Phase E: longest bad row run %d\n", t.longest_bad_row_run);
    printf( "Phase E: coding method %s\n", t4_encoding_to_str(t.encoding));
    printf( "Phase E: image size %d bytes\n", t.image_size);
    t30_get_local_ident(s, ident);
    printf( "Phase E: local ident '%s'\n", ident);
    t30_get_far_ident(s, ident);
    printf( "Phase E: remote ident '%s'\n", ident);
    if ((u = t30_get_far_country(s)))
        printf( "Phase E: Remote was made in '%s'\n", u);
    if ((u = t30_get_far_vendor(s)))
        printf( "Phase E: Remote was made by '%s'\n", u);
    if ((u = t30_get_far_model(s)))
        printf( "Phase E: Remote is model '%s'\n", u);
}
示例#4
0
/*
 *  Called at the end of the document
 */
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
	t30_stats_t t;
	const char *local_ident;
	const char *far_ident;
	const char *tmp;

	fax_session_t *f_session;

	t30_get_transfer_statistics(s, &t);
	f_session = (fax_session_t *)user_data;

	tmp = t30_get_tx_ident(s);
	local_ident = tmp ? tmp : "";
	tmp = t30_get_rx_ident(s);
	far_ident = tmp ? tmp : "";

	printf("fax: Phase E handler (Call: '%s' %s)\n", f_session->call_id,
		   f_session->pvt.caller ? "sender" : "receiver");
	printf("fax: ==============================================================================\n");

	if (result == T30_ERR_OK) {
		printf("fax: Fax successfully %s\n", f_session->pvt.caller ?
				   "sent" : "received");
	} else {
		printf("fax: Fax processing not successful - result (%d) %s\n", result,
						  t30_completion_code_to_str(result));
	}

	printf("fax: Remote station id: %s\n", far_ident);
	printf("fax: Local station id:  %s\n", local_ident);
	printf("fax: Pages transferred: %i\n", f_session->pvt.caller ?
			   t.pages_tx : t.pages_rx);
	printf("fax: Total fax pages:   %i\n", t.pages_in_file);
	printf("fax: Image resolution:  %ix%i\n", t.x_resolution, t.y_resolution);
	printf("fax: Transfer Rate:     %i\n", t.bit_rate);

	printf("fax: ECM status        %s\n", (t.error_correcting_mode) ? "on" : "off");
	printf("fax: remote country:   %s\n", (t30_get_rx_country(s) ? (t30_get_rx_country(s)) : ""));
	printf("fax: remote vendor:    %s\n", (t30_get_rx_vendor(s) ? (t30_get_rx_vendor(s)) : ""));
	printf("fax: remote model:     %s\n", (t30_get_rx_model(s) ? (t30_get_rx_model(s)) : ""));

	printf("fax: ==============================================================================\n");

	/*
	   Set our channel variables, variables are also used in event
	 */

	f_session->pvt.done = 1;

	if (result == T30_ERR_OK)
		f_session->fax_success = 1;
	else
		f_session->fax_success = 0;

	if(f_session->pvt.caller) sendRelese(f_session);
}
示例#5
0
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
    struct cw_channel *chan;
    char buf[128];
    t30_stats_t t;
    const char *tx_ident;
    const char *rx_ident;

    chan = (struct cw_channel *) user_data;
    t30_get_transfer_statistics(s, &t);
    
    tx_ident = t30_get_tx_ident(s);
    if (tx_ident == NULL)
        tx_ident = "";
    rx_ident = t30_get_rx_ident(s);
    if (rx_ident == NULL)
        rx_ident = "";
    pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", rx_ident);
    snprintf(buf, sizeof(buf), "%d", t.pages_rx);
    pbx_builtin_setvar_helper(chan, "FAXPAGES", buf);
    snprintf(buf, sizeof(buf), "%d", t.y_resolution);
    pbx_builtin_setvar_helper(chan, "FAXRESOLUTION", buf);
    snprintf(buf, sizeof(buf), "%d", t.bit_rate);
    pbx_builtin_setvar_helper(chan, "FAXBITRATE", buf);
    snprintf(buf, sizeof(buf), "%d", result);
    pbx_builtin_setvar_helper(chan, "PHASEESTATUS", buf);
    snprintf(buf, sizeof(buf), "%s", t30_completion_code_to_str(result));
    pbx_builtin_setvar_helper(chan, "PHASEESTRING", buf);

    cw_log(LOG_DEBUG, "==============================================================================\n");
    if (result == T30_ERR_OK)
    {
        cw_log(LOG_DEBUG, "Fax successfully received.\n");
        cw_log(LOG_DEBUG, "Remote station id: %s\n", rx_ident);
        cw_log(LOG_DEBUG, "Local station id:  %s\n", tx_ident);
        cw_log(LOG_DEBUG, "Pages transferred: %i\n", t.pages_rx);
        cw_log(LOG_DEBUG, "Image resolution:  %i x %i\n", t.x_resolution, t.y_resolution);
        cw_log(LOG_DEBUG, "Transfer Rate:     %i\n", t.bit_rate);
        manager_event(EVENT_FLAG_CALL,
                      "FaxSent", "Channel: %s\nExten: %s\nCallerID: %s\nRemoteStationID: %s\nLocalStationID: %s\nPagesTransferred: %i\nResolution: %i\nTransferRate: %i\nFileName: %s\n",
                      chan->name,
                      chan->exten,
                      (chan->cid.cid_num)  ?  chan->cid.cid_num  :  "",
                      rx_ident,
                      tx_ident,
                      t.pages_rx,
                      t.y_resolution,
                      t.bit_rate,
                      s->rx_file);
    }
    else
    {
        cw_log(LOG_DEBUG, "Fax receive not successful - result (%d) %s.\n", result, t30_completion_code_to_str(result));
    }
    cw_log(LOG_DEBUG, "==============================================================================\n");
}
示例#6
0
void fax_log_final_transfer_statistics(t30_state_t *s, const char *tag)
{
    t30_stats_t t;

    t30_get_transfer_statistics(s, &t);
    printf("%s: Bit rate %d\n", tag, t.bit_rate);
    printf("%s: ECM %s\n", tag, (t.error_correcting_mode)  ?  "on"  :  "off");
    printf("%s: RTP events %d. RTN events %d\n", tag, t.rtp_events, t.rtn_events);
    printf("%s: Tx pages %d, rx pages %d\n", tag, t.pages_tx, t.pages_rx);
}
示例#7
0
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
    int i;
    t30_stats_t t;
    char tag[20];

    i = (int) (intptr_t) user_data;
    snprintf(tag, sizeof(tag), "%c: Phase E", i);
    printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
    fax_log_final_transfer_statistics(s, tag);
    fax_log_tx_parameters(s, tag);
    fax_log_rx_parameters(s, tag);
    t30_get_transfer_statistics(s, &t);
}
示例#8
0
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
    int i;
    t30_stats_t t;
    char tag[20];
    
    i = (int) (intptr_t) user_data;
    snprintf(tag, sizeof(tag), "%c: Phase E", i + 'A');
    printf("%c: Phase E handler - (%d) %s\n", i + 'A', result, t30_completion_code_to_str(result));
    fax_log_final_transfer_statistics(s, tag);
    fax_log_tx_parameters(s, tag);
    fax_log_rx_parameters(s, tag);
    t30_get_transfer_statistics(s, &t);
    succeeded[i] = (result == T30_ERR_OK);
    phase_e_reached[i] = TRUE;
}
static void phase_e_handler(t30_state_t *s, void *user_data, int result)
{
    int i;
    t30_stats_t t;
    char tag[20];
    
    i = (int) (intptr_t) user_data;
    snprintf(tag, sizeof(tag), "%c: Phase E", i);
    printf("%c: Phase E handler on channel %c - (%d) %s\n", i, i, result, t30_completion_code_to_str(result));
    fax_log_final_transfer_statistics(s, tag);
    fax_log_tx_parameters(s, tag);
    fax_log_rx_parameters(s, tag);
    t30_get_transfer_statistics(s, &t);
    succeeded[i - 'A'] = (result == T30_ERR_OK)  &&  (t.pages_tx == 12  ||  t.pages_rx == 12);
    done[i - 'A'] = true;
}
示例#10
0
void fax_log_page_transfer_statistics(t30_state_t *s, const char *tag)
{
    t30_stats_t t;

    t30_get_transfer_statistics(s, &t);
    printf("%s: Page statistics\n", tag);
    printf("%s:   Pages in the file %d\n", tag, t.pages_in_file);
    printf("%s:   Bad rows %d, longest bad row run %d\n", tag, t.bad_rows, t.longest_bad_row_run);
    printf("%s:   Bad ECM frames %d\n", tag, t.error_correcting_mode_retries);
    printf("%s:   Compression type %s (%d)\n", tag, t4_encoding_to_str(t.encoding), t.encoding);
    printf("%s:   Compressed image size %d bytes\n", tag, t.image_size);
    printf("%s:   Image type %s (%s in the file)\n", tag, t4_image_type_to_str(t.type), t4_image_type_to_str(t.image_type));
    printf("%s:   Image size %d pels x %d pels (%d pels x %d pels in the file)\n", tag, t.width, t.length, t.image_width, t.image_length);
    printf("%s:   Image resolution %d pels/m x %d pels/m (%d pels/m x %d pels/m in the file)\n", tag, t.x_resolution, t.y_resolution, t.image_x_resolution, t.image_y_resolution);
#if defined(SPANDSP_EXPOSE_INTERNAL_STRUCTURES)
    printf("%s:   Bits per row - min %d, max %d\n", tag, s->t4.tx.encoder.t4_t6.min_row_bits, s->t4.tx.encoder.t4_t6.max_row_bits);
#endif

    fax_log_final_transfer_statistics(s, tag);
}
示例#11
0
static int phase_d_handler(t30_state_t *s, void *user_data, int result)
{
    struct cw_channel *chan;
    t30_stats_t t;
    
    chan = (struct cw_channel *) user_data;
    if (result)
    {
        t30_get_transfer_statistics(s, &t);
        cw_log(LOG_DEBUG, "==============================================================================\n");
        cw_log(LOG_DEBUG, "Pages transferred:  %i\n", t.pages_rx);
        cw_log(LOG_DEBUG, "Image size:         %i x %i\n", t.width, t.length);
        cw_log(LOG_DEBUG, "Image resolution    %i x %i\n", t.x_resolution, t.y_resolution);
        cw_log(LOG_DEBUG, "Transfer Rate:      %i\n", t.bit_rate);
        cw_log(LOG_DEBUG, "Bad rows            %i\n", t.bad_rows);
        cw_log(LOG_DEBUG, "Longest bad row run %i\n", t.longest_bad_row_run);
        cw_log(LOG_DEBUG, "Compression type    %s\n", t4_encoding_to_str(t.encoding));
        cw_log(LOG_DEBUG, "Image size (bytes)  %i\n", t.image_size);
        cw_log(LOG_DEBUG, "==============================================================================\n");
    }
    return T30_ERR_OK;
}
示例#12
0
static void phase_d_handler(t30_state_t *s, void *user_data, int result)
{
    int i;
    t30_stats_t t;
    char ident[21];

    i = (int) (intptr_t) user_data;
    printf("%c: Phase D handler on channel %c - (0x%X) %s\n", i, i, result, t30_frametype(result));
    t30_get_transfer_statistics(s, &t);
    printf("%c: Phase D: bit rate %d\n", i, t.bit_rate);
    printf("%c: Phase D: ECM %s\n", i, (t.error_correcting_mode)  ?  "on"  :  "off");
    printf("%c: Phase D: pages transferred %d\n", i, t.pages_transferred);
    printf("%c: Phase D: image size %d x %d\n", i, t.width, t.length);
    printf("%c: Phase D: image resolution %d x %d\n", i, t.x_resolution, t.y_resolution);
    printf("%c: Phase D: bad rows %d\n", i, t.bad_rows);
    printf("%c: Phase D: longest bad row run %d\n", i, t.longest_bad_row_run);
    printf("%c: Phase D: coding method %s\n", i, t4_encoding_to_str(t.encoding));
    printf("%c: Phase D: image size %d\n", i, t.image_size);
    t30_get_local_ident(s, ident);
    printf("%c: Phase D: local ident '%s'\n", i, ident);
    t30_get_far_ident(s, ident);
    printf("%c: Phase D: remote ident '%s'\n", i, ident);
}
示例#13
0
static int phase_d_handler(t30_state_t *s, void *user_data, int msg)
{
	t30_stats_t t30_stats;

	fax_session_t *f_session = (fax_session_t *)user_data;

	t30_get_transfer_statistics(s, &t30_stats);

	printf("fax: Phase D handler (Call: '%s' %s)\n", f_session->call_id,
		   f_session->pvt.caller ? "sender" : "receiver");
	printf("fax: ==== Page %s ===========================================================\n",
		   f_session->pvt.caller ? "Sent" : "Received");
	printf("fax: Page no = %d\n", f_session->pvt.caller ?
			   t30_stats.pages_tx : t30_stats.pages_rx);
	printf("fax: Image size = %d x %d pixels\n", t30_stats.width, t30_stats.length);
	printf("fax: Image resolution = %d/m x %d/m\n", t30_stats.x_resolution, t30_stats.y_resolution);
	printf("fax: Compressed image size = %d bytes\n", t30_stats.image_size);
	printf("fax: Bad rows = %d\n", t30_stats.bad_rows);
	printf("fax: Longest bad row run = %d\n", t30_stats.longest_bad_row_run);
	printf("fax: ==============================================================================\n");

	return T30_ERR_OK; /* I don't think this does anything */
}
示例#14
0
static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
{
	struct ast_channel *chan = (struct ast_channel *) user_data;

	struct ast_frame outf = {
		.frametype = AST_FRAME_MODEM,
		.subclass.integer = AST_MODEM_T38,
		.src = __FUNCTION__,
	};

	/* TODO: Asterisk does not provide means of resending the same packet multiple
	  times so count is ignored at the moment */

	AST_FRAME_SET_BUFFER(&outf, buf, 0, len);

	if (ast_write(chan, &outf) < 0) {
		ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
		return -1;
	}

	return 0;
}

static void phase_e_handler(t30_state_t *f, void *user_data, int result)
{
	const char *local_ident;
	const char *far_ident;
	char buf[20];
	fax_session *s = (fax_session *) user_data;
	t30_stats_t stat;
	int pages_transferred;

	ast_debug(1, "Fax phase E handler. result=%d\n", result);

	t30_get_transfer_statistics(f, &stat);

	s = (fax_session *) user_data;

	if (result != T30_ERR_OK) {
		s->finished = -1;

		/* FAXSTATUS is already set to FAILED */
		pbx_builtin_setvar_helper(s->chan, "FAXERROR", t30_completion_code_to_str(result));

		ast_log(LOG_WARNING, "Error transmitting fax. result=%d: %s.\n", result, t30_completion_code_to_str(result));

		return;
	}

	s->finished = 1;

	local_ident = S_OR(t30_get_tx_ident(f), "");
	far_ident = S_OR(t30_get_rx_ident(f), "");
	pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "SUCCESS");
	pbx_builtin_setvar_helper(s->chan, "FAXERROR", NULL);
	pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", far_ident);
#if SPANDSP_RELEASE_DATE >= 20090220
	pages_transferred = (s->direction) ? stat.pages_tx : stat.pages_rx;
#else
	pages_transferred = stat.pages_transferred;
#endif
	snprintf(buf, sizeof(buf), "%d", pages_transferred);
	pbx_builtin_setvar_helper(s->chan, "FAXPAGES", buf);
	snprintf(buf, sizeof(buf), "%d", stat.y_resolution);
	pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", buf);
	snprintf(buf, sizeof(buf), "%d", stat.bit_rate);
	pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", buf);

	ast_debug(1, "Fax transmitted successfully.\n");
	ast_debug(1, "  Remote station ID: %s\n", far_ident);
	ast_debug(1, "  Pages transferred: %d\n", pages_transferred);
	ast_debug(1, "  Image resolution:  %d x %d\n", stat.x_resolution, stat.y_resolution);
	ast_debug(1, "  Transfer Rate:     %d\n", stat.bit_rate);

	ast_manager_event(s->chan, EVENT_FLAG_CALL,
		s->direction ? "FaxSent" : "FaxReceived",
		"Channel: %s\r\n"
		"Exten: %s\r\n"
		"CallerID: %s\r\n"
		"CallerIDName: %s\r\n"
		"ConnectedLineNum: %s\r\n"
		"ConnectedLineName: %s\r\n"
		"RemoteStationID: %s\r\n"
		"LocalStationID: %s\r\n"
		"PagesTransferred: %d\r\n"
		"Resolution: %d\r\n"
		"TransferRate: %d\r\n"
		"FileName: %s\r\n",
		ast_channel_name(s->chan),
		ast_channel_exten(s->chan),
		S_COR(ast_channel_caller(s->chan)->id.number.valid, ast_channel_caller(s->chan)->id.number.str, ""),
		S_COR(ast_channel_caller(s->chan)->id.name.valid, ast_channel_caller(s->chan)->id.name.str, ""),
		S_COR(ast_channel_connected(s->chan)->id.number.valid, ast_channel_connected(s->chan)->id.number.str, ""),
		S_COR(ast_channel_connected(s->chan)->id.name.valid, ast_channel_connected(s->chan)->id.name.str, ""),
		far_ident,
		local_ident,
		pages_transferred,
		stat.y_resolution,
		stat.bit_rate,
		s->file_name);
}

/* === Helper functions to configure fax === */

/* Setup SPAN logging according to Asterisk debug level */
static int set_logging(logging_state_t *state)
{
	int level = SPAN_LOG_WARNING + option_debug;

	span_log_set_message_handler(state, span_message);
	span_log_set_level(state, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | level); 

	return 0;
}
示例#15
0
static void phase_e_handler(t30_state_t *f, void *user_data, int result)
{
	const char *local_ident;
	const char *far_ident;
	char buf[20];
	fax_session *s = (fax_session *) user_data;
	t30_stats_t stat;

	ast_debug(1, "Fax phase E handler. result=%d\n", result);

	t30_get_transfer_statistics(f, &stat);

	s = (fax_session *) user_data;

	if (result != T30_ERR_OK) {
		s->finished = -1;

		/* FAXSTATUS is already set to FAILED */
		pbx_builtin_setvar_helper(s->chan, "FAXERROR", t30_completion_code_to_str(result));

		ast_log(LOG_WARNING, "Error transmitting fax. result=%d: %s.\n", result, t30_completion_code_to_str(result));

		return;
	}
	
	s->finished = 1; 
	
	local_ident = t30_get_tx_ident(f);
	far_ident = t30_get_rx_ident(f);
	pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "SUCCESS"); 
	pbx_builtin_setvar_helper(s->chan, "FAXERROR", NULL); 
	pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", far_ident);
	snprintf(buf, sizeof(buf), "%d", stat.pages_transferred);
	pbx_builtin_setvar_helper(s->chan, "FAXPAGES", buf);
	snprintf(buf, sizeof(buf), "%d", stat.y_resolution);
	pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", buf);
	snprintf(buf, sizeof(buf), "%d", stat.bit_rate);
	pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", buf); 
	
	ast_debug(1, "Fax transmitted successfully.\n");
	ast_debug(1, "  Remote station ID: %s\n", far_ident);
	ast_debug(1, "  Pages transferred: %d\n", stat.pages_transferred);
	ast_debug(1, "  Image resolution:  %d x %d\n", stat.x_resolution, stat.y_resolution);
	ast_debug(1, "  Transfer Rate:     %d\n", stat.bit_rate);
	
	manager_event(EVENT_FLAG_CALL,
		      s->direction ? "FaxSent" : "FaxReceived", 
		      "Channel: %s\r\n"
		      "Exten: %s\r\n"
		      "CallerID: %s\r\n"
		      "RemoteStationID: %s\r\n"
		      "LocalStationID: %s\r\n"
		      "PagesTransferred: %d\r\n"
		      "Resolution: %d\r\n"
		      "TransferRate: %d\r\n"
		      "FileName: %s\r\n",
		      s->chan->name,
		      s->chan->exten,
		      S_OR(s->chan->cid.cid_num, ""),
		      far_ident,
		      local_ident,
		      stat.pages_transferred,
		      stat.y_resolution,
		      stat.bit_rate,
		      s->file_name);
}
示例#16
0
static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count)
{
	struct ast_channel *chan = (struct ast_channel *) user_data;

	struct ast_frame outf = {
		.frametype = AST_FRAME_MODEM,
		.subclass.integer = AST_MODEM_T38,
		.src = __FUNCTION__,
	};

	/* TODO: Asterisk does not provide means of resending the same packet multiple
	  times so count is ignored at the moment */

	AST_FRAME_SET_BUFFER(&outf, buf, 0, len);

	if (ast_write(chan, &outf) < 0) {
		ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno));
		return -1;
	}

	return 0;
}

static void phase_e_handler(t30_state_t *f, void *user_data, int result)
{
	RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
	RAII_VAR(struct ast_json *, json_filenames, NULL, ast_json_unref);
	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
	const char *local_ident;
	const char *far_ident;
	char buf[20];
	fax_session *s = (fax_session *) user_data;
	t30_stats_t stat;
	int pages_transferred;

	ast_debug(1, "Fax phase E handler. result=%d\n", result);

	t30_get_transfer_statistics(f, &stat);

	s = (fax_session *) user_data;

	if (result != T30_ERR_OK) {
		s->finished = -1;

		/* FAXSTATUS is already set to FAILED */
		pbx_builtin_setvar_helper(s->chan, "FAXERROR", t30_completion_code_to_str(result));

		ast_log(LOG_WARNING, "Error transmitting fax. result=%d: %s.\n", result, t30_completion_code_to_str(result));

		return;
	}

	s->finished = 1;

	local_ident = S_OR(t30_get_tx_ident(f), "");
	far_ident = S_OR(t30_get_rx_ident(f), "");
	pbx_builtin_setvar_helper(s->chan, "FAXSTATUS", "SUCCESS");
	pbx_builtin_setvar_helper(s->chan, "FAXERROR", NULL);
	pbx_builtin_setvar_helper(s->chan, "REMOTESTATIONID", far_ident);
#if SPANDSP_RELEASE_DATE >= 20090220
	pages_transferred = (s->direction) ? stat.pages_tx : stat.pages_rx;
#else
	pages_transferred = stat.pages_transferred;
#endif
	snprintf(buf, sizeof(buf), "%d", pages_transferred);
	pbx_builtin_setvar_helper(s->chan, "FAXPAGES", buf);
	snprintf(buf, sizeof(buf), "%d", stat.y_resolution);
	pbx_builtin_setvar_helper(s->chan, "FAXRESOLUTION", buf);
	snprintf(buf, sizeof(buf), "%d", stat.bit_rate);
	pbx_builtin_setvar_helper(s->chan, "FAXBITRATE", buf);

	ast_debug(1, "Fax transmitted successfully.\n");
	ast_debug(1, "  Remote station ID: %s\n", far_ident);
	ast_debug(1, "  Pages transferred: %d\n", pages_transferred);
	ast_debug(1, "  Image resolution:  %d x %d\n", stat.x_resolution, stat.y_resolution);
	ast_debug(1, "  Transfer Rate:     %d\n", stat.bit_rate);

	json_filenames = ast_json_pack("[s]", s->file_name);
	if (!json_filenames) {
		return;
	}
	ast_json_ref(json_filenames);
	json_object = ast_json_pack("{s: s, s: s, s: s, s: i, s: i, s: i, s: o}",
			"type", s->direction ? "send" : "receive",
			"remote_station_id", far_ident,
			"local_station_id", local_ident,
			"fax_pages", pages_transferred,
			"fax_resolution", stat.y_resolution,
			"fax_bitrate", stat.bit_rate,
			"filenames", json_filenames);
	message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(s->chan), ast_channel_fax_type(), json_object);
	if (!message) {
		return;
	}
	stasis_publish(ast_channel_topic(s->chan), message);
}