/* * 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); }
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"); }
void fax_log_rx_parameters(t30_state_t *s, const char *tag) { const char *u; if ((u = t30_get_rx_ident(s))) printf("%s: Remote ident '%s'\n", tag, u); if ((u = t30_get_rx_sub_address(s))) printf("%s: Remote sub-address '%s'\n", tag, u); if ((u = t30_get_rx_polled_sub_address(s))) printf("%s: Remote polled sub-address '%s'\n", tag, u); if ((u = t30_get_rx_selective_polling_address(s))) printf("%s: Remote selective polling address '%s'\n", tag, u); if ((u = t30_get_rx_sender_ident(s))) printf("%s: Remote sender ident '%s'\n", tag, u); if ((u = t30_get_rx_password(s))) printf("%s: Remote password '%s'\n", tag, u); if ((u = t30_get_rx_country(s))) printf("%s: Remote was made in '%s'\n", tag, u); if ((u = t30_get_rx_vendor(s))) printf("%s: Remote was made by '%s'\n", tag, u); if ((u = t30_get_rx_model(s))) printf("%s: Remote is model '%s'\n", tag, u); }
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; }
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); }
static int phase_b_handler(t30_state_t *s, void *user_data, int result) { int i; int ch; int status; int len; char tag[20]; const char *u; const uint8_t *v; i = (int) (intptr_t) user_data; ch = i + 'A'; snprintf(tag, sizeof(tag), "%c: Phase B", ch); printf("%c: Phase B handler - (0x%X) %s\n", ch, result, t30_frametype(result)); fax_log_rx_parameters(s, tag); status = T30_ERR_OK; if ((u = t30_get_rx_ident(s))) { printf("%c: Phase B remote ident '%s'\n", ch, u); if (expected_rx_info[i].ident[0] && strcmp(expected_rx_info[i].ident, u)) { printf("%c: Phase B: remote ident incorrect! - expected '%s'\n", ch, expected_rx_info[i].ident); status = T30_ERR_IDENT_UNACCEPTABLE; } } else { if (expected_rx_info[i].ident[0]) { printf("%c: Phase B: remote ident missing!\n", ch); status = T30_ERR_IDENT_UNACCEPTABLE; } } if ((u = t30_get_rx_sub_address(s))) { printf("%c: Phase B: remote sub-address '%s'\n", ch, u); if (expected_rx_info[i].sub_address[0] && strcmp(expected_rx_info[i].sub_address, u)) { printf("%c: Phase B: remote sub-address incorrect! - expected '%s'\n", ch, expected_rx_info[i].sub_address); status = T30_ERR_SUB_UNACCEPTABLE; } } else { if (expected_rx_info[i].sub_address[0]) { printf("%c: Phase B: remote sub-address missing!\n", ch); status = T30_ERR_SUB_UNACCEPTABLE; } } if ((u = t30_get_rx_polled_sub_address(s))) { printf("%c: Phase B: remote polled sub-address '%s'\n", ch, u); if (expected_rx_info[i].polled_sub_address[0] && strcmp(expected_rx_info[i].polled_sub_address, u)) { printf("%c: Phase B: remote polled sub-address incorrect! - expected '%s'\n", ch, expected_rx_info[i].polled_sub_address); status = T30_ERR_PSA_UNACCEPTABLE; } } else { if (expected_rx_info[i].polled_sub_address[0]) { printf("%c: Phase B: remote polled sub-address missing!\n", ch); status = T30_ERR_PSA_UNACCEPTABLE; } } if ((u = t30_get_rx_selective_polling_address(s))) { printf("%c: Phase B: remote selective polling address '%s'\n", ch, u); if (expected_rx_info[i].selective_polling_address[0] && strcmp(expected_rx_info[i].selective_polling_address, u)) { printf("%c: Phase B: remote selective polling address incorrect! - expected '%s'\n", ch, expected_rx_info[i].selective_polling_address); status = T30_ERR_SEP_UNACCEPTABLE; } } else { if (expected_rx_info[i].selective_polling_address[0]) { printf("%c: Phase B: remote selective polling address missing!\n", ch); status = T30_ERR_SEP_UNACCEPTABLE; } } if ((u = t30_get_rx_sender_ident(s))) { printf("%c: Phase B: remote sender ident '%s'\n", ch, u); if (expected_rx_info[i].sender_ident[0] && strcmp(expected_rx_info[i].sender_ident, u)) { printf("%c: Phase B: remote sender ident incorrect! - expected '%s'\n", ch, expected_rx_info[i].sender_ident); status = T30_ERR_SID_UNACCEPTABLE; } } else { if (expected_rx_info[i].sender_ident[0]) { printf("%c: Phase B: remote sender ident missing!\n", ch); status = T30_ERR_SID_UNACCEPTABLE; } } if ((u = t30_get_rx_password(s))) { printf("%c: Phase B: remote password '%s'\n", ch, u); if (expected_rx_info[i].password[0] && strcmp(expected_rx_info[i].password, u)) { printf("%c: Phase B: remote password incorrect! - expected '%s'\n", ch, expected_rx_info[i].password); status = T30_ERR_PWD_UNACCEPTABLE; } } else { if (expected_rx_info[i].password[0]) { printf("%c: Phase B: remote password missing!\n", ch); status = T30_ERR_PWD_UNACCEPTABLE; } } if ((len = t30_get_rx_nsf(s, &v))) { printf("%c: Phase B: NSF %d bytes\n", ch, len); if (expected_rx_info[i].nsf_len && (expected_rx_info[i].nsf_len != len || memcmp(expected_rx_info[i].nsf, v, len))) { printf("%c: Phase B: remote NSF incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); } } else { if (expected_rx_info[i].nsf_len) { printf("%c: Phase B: remote NSF missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); } } if ((len = t30_get_rx_nsc(s, &v))) { printf("%c: Phase B: NSC %d bytes\n", ch, len); if (expected_rx_info[i].nsc_len && (expected_rx_info[i].nsc_len != len || memcmp(expected_rx_info[i].nsc, v, len))) { printf("%c: Phase B: remote NSC incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsc_len); } } else { if (expected_rx_info[i].nsc_len) { printf("%c: Phase B: remote NSC missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsc_len); } } if ((len = t30_get_rx_nss(s, &v))) { printf("%c: Phase B: NSS %d bytes\n", ch, len); if (expected_rx_info[i].nss_len && (expected_rx_info[i].nss_len != len || memcmp(expected_rx_info[i].nss, v, len))) { printf("%c: Phase B: remote NSS incorrect! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nss_len); } } else { if (expected_rx_info[i].nss_len) { printf("%c: Phase B: remote NSS missing! - expected %u bytes\n", ch, (unsigned int) expected_rx_info[i].nsf_len); } } return status; }
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); }