52 #define ASTMM_LIBC ASTMM_IGNORE 66 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES 68 #include <spandsp/version.h> 70 #define SPANDSP_FAX_SAMPLES 160 71 #define SPANDSP_FAX_TIMER_RATE 8000 / SPANDSP_FAX_SAMPLES 72 #define SPANDSP_ENGAGE_UDPTL_NAT_RETRY 3 97 .description =
"Spandsp FAX Driver",
98 #if SPANDSP_RELEASE_DATE >= 20090220 100 .version = SPANDSP_RELEASE_DATETIME_STRING,
105 .version =
"pre-20090220",
171 static void spandsp_log(
int level,
const char *msg);
183 t30_state_t *t30_to_terminate;
187 }
else if (p->
ist38) {
188 #if SPANDSP_RELEASE_DATE >= 20080725 191 t30_to_terminate = &p->
t38_state.t30_state;
194 #if SPANDSP_RELEASE_DATE >= 20080725 197 t30_to_terminate = &p->
fax_state.t30_state;
201 t30_terminate(t30_to_terminate);
225 .src =
"res_fax_spandsp_t38",
259 switch (completion_code) {
265 case T30_ERR_CEDTONE:
266 case T30_ERR_T0_EXPIRED:
267 case T30_ERR_T1_EXPIRED:
268 case T30_ERR_T3_EXPIRED:
269 case T30_ERR_HDLC_CARRIER:
270 case T30_ERR_CANNOT_TRAIN:
274 case T30_ERR_OPER_INT_FAIL:
275 case T30_ERR_INCOMPATIBLE:
276 case T30_ERR_RX_INCAPABLE:
277 case T30_ERR_TX_INCAPABLE:
278 case T30_ERR_NORESSUPPORT:
279 case T30_ERR_NOSIZESUPPORT:
283 case T30_ERR_UNEXPECTED:
288 case T30_ERR_TX_BADDCS:
289 case T30_ERR_TX_BADPG:
290 case T30_ERR_TX_ECMPHD:
291 case T30_ERR_TX_GOTDCN:
292 case T30_ERR_TX_INVALRSP:
293 case T30_ERR_TX_NODIS:
294 case T30_ERR_TX_PHBDEAD:
295 case T30_ERR_TX_PHDDEAD:
296 case T30_ERR_TX_T5EXP:
301 case T30_ERR_RX_ECMPHD:
302 case T30_ERR_RX_GOTDCS:
303 case T30_ERR_RX_INVALCMD:
304 case T30_ERR_RX_NOCARRIER:
305 case T30_ERR_RX_NOEOL:
308 case T30_ERR_RX_NOFAX:
311 case T30_ERR_RX_T2EXPDCN:
312 case T30_ERR_RX_T2EXPD:
313 case T30_ERR_RX_T2EXPFAX:
314 case T30_ERR_RX_T2EXPMPS:
315 case T30_ERR_RX_T2EXPRR:
316 case T30_ERR_RX_T2EXP:
317 case T30_ERR_RX_DCNWHY:
318 case T30_ERR_RX_DCNDATA:
319 case T30_ERR_RX_DCNFAX:
320 case T30_ERR_RX_DCNPHD:
321 case T30_ERR_RX_DCNRRD:
322 case T30_ERR_RX_DCNNORTN:
327 case T30_ERR_FILEERROR:
329 case T30_ERR_BADTIFF:
330 case T30_ERR_BADPAGE:
332 case T30_ERR_BADTIFFHDR:
340 case T30_ERR_RETRYDCN:
343 case T30_ERR_CALLDROPPED:
349 case T30_ERR_IDENT_UNACCEPTABLE:
350 case T30_ERR_SUB_UNACCEPTABLE:
351 case T30_ERR_SEP_UNACCEPTABLE:
352 case T30_ERR_PSA_UNACCEPTABLE:
353 case T30_ERR_SID_UNACCEPTABLE:
354 case T30_ERR_PWD_UNACCEPTABLE:
355 case T30_ERR_TSA_UNACCEPTABLE:
356 case T30_ERR_IRA_UNACCEPTABLE:
357 case T30_ERR_CIA_UNACCEPTABLE:
358 case T30_ERR_ISP_UNACCEPTABLE:
359 case T30_ERR_CSA_UNACCEPTABLE:
364 ast_log(
LOG_WARNING,
"unknown FAX session result '%d' (%s)\n", completion_code, t30_completion_code_to_str(completion_code));
382 char headerinfo[T30_MAX_PAGE_HEADER_INFO + 1];
386 ast_debug(5,
"FAX session '%u' entering phase E\n", s->
id);
392 t30_get_transfer_statistics(t30_state, &stats);
394 if (completion_code == T30_ERR_OK) {
405 if ((c = t30_get_tx_ident(t30_state))) {
409 if ((c = t30_get_rx_ident(t30_state))) {
413 #if SPANDSP_RELEASE_DATE >= 20090220 423 t30_get_tx_page_header_info(t30_state, headerinfo);
435 if (level == SPAN_LOG_ERROR) {
437 }
else if (level == SPAN_LOG_WARNING) {
446 int level = SPAN_LOG_WARNING;
449 level = SPAN_LOG_DEBUG_3;
453 span_log_set_level(state, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | level);
463 t30_set_tx_page_header_info(t30_state, details->
headerinfo);
481 t30_set_ecm_capability(t30_state, details->
option.
ecm);
482 t30_set_supported_compressions(t30_state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
503 modems |= T30_SUPPORT_V17;
506 modems |= T30_SUPPORT_V27TER;
509 modems |= T30_SUPPORT_V29;
512 #if defined(T30_SUPPORT_V34) 513 modems |= T30_SUPPORT_V34;
514 #elif defined(T30_SUPPORT_V34HDX) 515 modems |= T30_SUPPORT_V34HDX;
531 ast_log(
LOG_ERROR,
"Cannot initialize the spandsp private FAX technology structure.\n");
537 ast_log(
LOG_ERROR,
"Cannot initialize the spandsp private v21 technology structure.\n");
556 ast_log(
LOG_ERROR,
"Are we sending or receiving? The FAX requirements (capabilities: 0x%X) were not properly set.\n", s->
details->
caps);
631 .src =
"res_fax_spandsp_g711",
644 ast_debug(5,
"FAX session '%u' is complete.\n", s->
id);
668 if (code == MODEM_CONNECT_TONES_FAX_PREAMBLE) {
677 g711_state_t *decoder;
688 ast_debug(5,
"frame={ datalen=%d, samples=%d, mallocd=%d, src=%s, flags=%u, ts=%ld, len=%ld, seqno=%d, data.ptr=%p, subclass.format=%s }\n", f->
datalen, f->
samples, f->
mallocd, f->
src, f->
flags, f->
ts, f->
len, f->
seqno, f->
data.
ptr,
ast_format_get_name(f->
subclass.
format));
704 g711_release(decoder);
705 #if SPANDSP_RELEASE_DATE >= 20090220 775 .src =
"res_fax_spandsp_g711",
783 return p->
isdone ? -1 : res;
792 return p->
isdone ? -1 : res;
825 #if SPANDSP_RELEASE_DATE >= 20081012 876 #if SPANDSP_RELEASE_DATE >= 20091228 877 t38_core_send_indicator(&p->
t38_gw_state.t38x.t38, T38_IND_NO_SIGNAL);
878 #elif SPANDSP_RELEASE_DATE >= 20081012 919 t38_stats_t t38_stats;
921 t38_gateway_get_transfer_statistics(&p->
t38_gw_state, &t38_stats);
940 #if SPANDSP_RELEASE_DATE >= 20080725 950 #if SPANDSP_RELEASE_DATE >= 20080725 990 fax_set_transmit_on_idle(&p->
fax_state, 1);
1043 ast_cli(fd,
"SEND RECEIVE T.38 G.711 GATEWAY\n\n");
1054 ast_cli(fd,
"%-22s : %u\n",
"session", s->
id);
1055 ast_cli(fd,
"%-22s : %s\n",
"operation",
"Gateway");
1059 t38_gateway_get_transfer_statistics(&p->
t38_gw_state, &stats);
1060 ast_cli(fd,
"%-22s : %s\n",
"ECM Mode", stats.error_correcting_mode ?
"Yes" :
"No");
1061 ast_cli(fd,
"%-22s : %d\n",
"Data Rate", stats.bit_rate);
1062 ast_cli(fd,
"%-22s : %d\n",
"Page Number", stats.pages_transferred + 1);
1065 ast_cli(fd,
"%-22s : %u\n",
"session", s->
id);
1066 ast_cli(fd,
"%-22s : %s\n",
"operation",
"V.21 Detect");
1071 ast_cli(fd,
"%-22s : %u\n",
"session", s->
id);
1076 t30_get_transfer_statistics(p->
t30_state, &stats);
1077 ast_cli(fd,
"%-22s : %s\n",
"Last Status", t30_completion_code_to_str(stats.current_status));
1078 ast_cli(fd,
"%-22s : %s\n",
"ECM Mode", stats.error_correcting_mode ?
"Yes" :
"No");
1079 ast_cli(fd,
"%-22s : %d\n",
"Data Rate", stats.bit_rate);
1080 ast_cli(fd,
"%-22s : %dx%d\n",
"Image Resolution", stats.x_resolution, stats.y_resolution);
1081 #if SPANDSP_RELEASE_DATE >= 20090220 1084 ast_cli(fd,
"%-22s : %d\n",
"Page Number", stats.pages_transferred + 1);
1088 ast_cli(fd,
"\nData Statistics:\n");
1089 #if SPANDSP_RELEASE_DATE >= 20090220 1090 ast_cli(fd,
"%-22s : %d\n",
"Tx Pages", stats.pages_tx);
1091 ast_cli(fd,
"%-22s : %d\n",
"Rx Pages", stats.pages_rx);
1096 ast_cli(fd,
"%-22s : %d\n",
"Longest Bad Line Run", stats.longest_bad_row_run);
1097 ast_cli(fd,
"%-22s : %d\n",
"Total Bad Lines", stats.bad_rows);
1108 struct ast_str *message_string;
1114 if (!message_string) {
1119 res =
ast_str_append(&message_string, 0,
"SessionNumber: %u\r\n", session->
id);
1127 goto skip_cap_additions;
1130 t38_gateway_get_transfer_statistics(&span_pvt->
t38_gw_state, &stats);
1131 res |=
ast_str_append(&message_string, 0,
"ErrorCorrectionMode: %s\r\n",
1132 stats.error_correcting_mode ?
"yes" :
"no");
1136 stats.pages_transferred + 1);
1141 goto skip_cap_additions;
1144 t30_get_transfer_statistics(span_pvt->
t30_state, &stats);
1145 res |=
ast_str_append(&message_string, 0,
"ErrorCorrectionMode: %s\r\n",
1146 stats.error_correcting_mode ?
"Yes" :
"No");
1149 res |=
ast_str_append(&message_string, 0,
"ImageResolution: %dx%d\r\n",
1150 stats.x_resolution, stats.y_resolution);
1151 #if SPANDSP_RELEASE_DATE >= 20090220 1156 stats.pages_transferred + 1);
1161 #if SPANDSP_RELEASE_DATE >= 20090220 1162 res |=
ast_str_append(&message_string, 0,
"PagesTransmitted: %d\r\n",
1164 res |=
ast_str_append(&message_string, 0,
"PagesReceived: %d\r\n",
1167 res |=
ast_str_append(&message_string, 0,
"PagesTransmitted: %d\r\n",
1169 res |=
ast_str_append(&message_string, 0,
"PagesReceived: %d\r\n",
1172 res |=
ast_str_append(&message_string, 0,
"TotalBadLines: %d\r\n",
1200 ast_cli(fd,
"\n%-20.20s\n",
"Spandsp G.711");
1215 ast_cli(fd,
"\n%-20.20s\n",
"Spandsp T.38");
1259 span_set_message_handler(
NULL);
1269 .enhances =
"res_fax",
static enum ast_t38_state ast_channel_get_t38_state(struct ast_channel *chan)
Retrieves the current T38 state of a channel.
const ast_string_field result
static void session_destroy(struct spandsp_pvt *p)
Main Channel structure associated with a channel.
struct spandsp_fax_stats g711
#define AST_FAX_FRFLAG_GATEWAY
static int spandsp_v21_detect(struct ast_fax_session *s, const struct ast_frame *f)
void astman_append(struct mansession *s, const char *fmt,...)
Asterisk main include file. File version handling, generic pbx functions.
static int spandsp_modems(struct ast_fax_session_details *details)
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
static void spandsp_fax_gateway_cleanup(struct ast_fax_session *s)
gather data and clean up after gateway ends
t38_terminal_state_t t38_state
void ast_fax_tech_unregister(struct ast_fax_tech *tech)
unregister a fax technology
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
static int spandsp_fax_gw_t30_gen(struct ast_channel *chan, void *data, int len, int samples)
generate T.30 packets sent to the T.30 leg of gateway
String manipulation functions.
static char * spandsp_fax_cli_show_settings(int fd)
Show res_fax_spandsp settings.
static char * spandsp_fax_cli_show_capabilities(int fd)
const ast_string_field headerinfo
void *(* alloc)(struct ast_channel *chan, void *params)
int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, void *params)
static struct @462 spandsp_global_stats
static int spandsp_fax_start(struct ast_fax_session *s)
#define ast_set_flag(p, flag)
static void spandsp_fax_gw_gen_release(struct ast_channel *chan, void *data)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static void set_ecm(t30_state_t *t30_state, struct ast_fax_session_details *details)
static int spandsp_fax_switch_to_t38(struct ast_fax_session *s)
static void spandsp_v21_tone(void *data, int code, int level, int delay)
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
struct ast_timer * ast_timer_open(void)
Open a timer.
ast_t38_state
Possible T38 states on channels.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static struct ast_frame * spandsp_fax_read(struct ast_fax_session *s)
Read a frame from the spandsp fax stack.
static struct ast_fax_tech spandsp_fax_tech
#define ast_mutex_lock(a)
static int t38_tx_packet_handler(t38_core_state_t *t38_core_state, void *data, const uint8_t *buf, int len, int count)
static int spandsp_fax_cancel(struct ast_fax_session *s)
struct spandsp_fax_stats t38
struct ast_channel * chan
void ast_cli(int fd, const char *fmt,...)
static int spandsp_fax_gateway_process(struct ast_fax_session *s, const struct ast_frame *f)
process a frame from the bridge
static int spandsp_fax_gateway_start(struct ast_fax_session *s)
activate a spandsp gateway based on the information in the given fax session
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
struct spandsp_pvt::frame_queue read_frames
struct ast_frame_subclass subclass
static void spandsp_v21_cleanup(struct ast_fax_session *s)
t38_core_state_t * t38_core_state
#define ast_strlen_zero(foo)
const char * ast_fax_session_operation_str(struct ast_fax_session *s)
get string representation of a FAX session's operation
union ast_fax_session_details::@290 option
struct spandsp_fax_gw_stats * t38stats
#define ast_debug(level,...)
Log a DEBUG message.
struct ast_fax_t38_parameters our_t38_parameters
static void spandsp_manager_fax_session(struct mansession *s, const char *id_text, struct ast_fax_session *session)
General Asterisk PBX channel definitions.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static struct ast_mansession session
#define ao2_ref(o, delta)
struct ast_fax_session_details * details
In case you didn't read that giant block of text above the mansession_session struct, the struct mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
static char * spandsp_fax_cli_show_session(struct ast_fax_session *s, int fd)
t38_gateway_state_t t38_gw_state
The data communicated between the high level applications and the generic fax function.
#define ast_malloc(len)
A wrapper for malloc()
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
struct ast_module * module
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
static void t30_phase_e_handler(t30_state_t *t30_state, void *data, int completion_code)
Phase E handler callback.
static void set_logging(logging_state_t *state, struct ast_fax_session_details *details)
unsigned int transcoding_mmr
unsigned int transcoding_jbig
modem_connect_tones_rx_state_t * tone_state
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
struct spandsp_fax_stats * stats
unsigned int pages_transferred
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static void spandsp_fax_destroy(struct ast_fax_session *s)
Destroy a spandsp fax session.
static int load_module(void)
load res_fax_spandsp
struct ast_fax_documents documents
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
used to register a FAX technology module with res_fax
static int update_stats(struct spandsp_pvt *p, int completion_code)
enum ast_t38_state ast_t38_state
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define ast_calloc(num, len)
A wrapper for calloc()
static void set_file(t30_state_t *t30_state, struct ast_fax_session_details *details)
enum ast_fax_modems modems
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Module has failed to load, may be in an inconsistent state.
void ast_fax_log(int level, const char *file, const int line, const char *function, const char *msg)
Log message at FAX or recommended level.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
static int unload_module(void)
unload res_fax_spandsp
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
static int spandsp_fax_write(struct ast_fax_session *s, const struct ast_frame *f)
Write a frame to the spandsp fax stack.
static void set_local_info(t30_state_t *t30_state, struct ast_fax_session_details *details)
Support for logging to various files, console and syslog Configuration in file logger.conf.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
static char * spandsp_fax_cli_show_stats(int fd)
struct ast_frame ast_null_frame
static void spandsp_log(int level, const char *msg)
Send spandsp log messages to asterisk.
#define SPANDSP_ENGAGE_UDPTL_NAT_RETRY
Standard Command Line Interface.
#define SPANDSP_FAX_TIMER_RATE
#define SPANDSP_FAX_SAMPLES
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
The data required to handle a fax session.
const char * ast_fax_state_to_str(enum ast_fax_state state)
convert an ast_fax_state to a string
Data structure associated with a single frame of data.
enum ast_control_t38_rate_management rate_management
enum ast_fax_capabilities caps
int error(const char *format,...)
const ast_string_field resultstr
union ast_frame::@263 data
enum ast_frame_type frametype
const ast_string_field localstationid
#define ast_mutex_init(pmutex)
#define ast_mutex_destroy(a)
struct ast_format * format
static void * spandsp_fax_new(struct ast_fax_session *s, struct ast_fax_tech_token *token)
create an instance of the spandsp tech_pvt for a fax session
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
unsigned int fill_bit_removal
struct ast_fax_t38_parameters their_t38_parameters
static int spandsp_v21_new(struct spandsp_pvt *p)
Timing source management.
Structure for mutex and tracking information.
static void * spandsp_fax_gw_gen_alloc(struct ast_channel *chan, void *params)
simple routine to allocate data to generator
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_fax_tech_register(struct ast_fax_tech *tech)
register a fax technology
#define ast_mutex_unlock(a)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.