Beispiel #1
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;
}
Beispiel #2
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);
}
Beispiel #3
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");
}
Beispiel #4
0
void fax_log_tx_parameters(t30_state_t *s, const char *tag)
{
    const char *u;
    
    if ((u = t30_get_tx_ident(s)))
        printf("%s: Local ident '%s'\n", tag, u);
    if ((u = t30_get_tx_sub_address(s)))
        printf("%s: Local sub-address '%s'\n", tag, u);
    if ((u = t30_get_tx_polled_sub_address(s)))
        printf("%s: Local polled sub-address '%s'\n", tag, u);
    if ((u = t30_get_tx_selective_polling_address(s)))
        printf("%s: Local selective polling address '%s'\n", tag, u);
    if ((u = t30_get_tx_sender_ident(s)))
        printf("%s: Local sender ident '%s'\n", tag, u);
    if ((u = t30_get_tx_password(s)))
        printf("%s: Local password '%s'\n", tag, u);
}
Beispiel #5
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;
}
Beispiel #6
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);
}
Beispiel #7
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);
}