00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include "asterisk.h"
00052
00053 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 361155 $")
00054
00055 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
00056 #include <spandsp.h>
00057 #include <spandsp/version.h>
00058
00059 #include "asterisk/logger.h"
00060 #include "asterisk/module.h"
00061 #include "asterisk/strings.h"
00062 #include "asterisk/cli.h"
00063 #include "asterisk/utils.h"
00064 #include "asterisk/timing.h"
00065 #include "asterisk/astobj2.h"
00066 #include "asterisk/res_fax.h"
00067 #include "asterisk/channel.h"
00068
00069 #define SPANDSP_FAX_SAMPLES 160
00070 #define SPANDSP_FAX_TIMER_RATE 8000 / SPANDSP_FAX_SAMPLES
00071 #define SPANDSP_ENGAGE_UDPTL_NAT_RETRY 3
00072
00073 static void *spandsp_fax_new(struct ast_fax_session *s, struct ast_fax_tech_token *token);
00074 static void spandsp_fax_destroy(struct ast_fax_session *s);
00075 static struct ast_frame *spandsp_fax_read(struct ast_fax_session *s);
00076 static int spandsp_fax_write(struct ast_fax_session *s, const struct ast_frame *f);
00077 static int spandsp_fax_start(struct ast_fax_session *s);
00078 static int spandsp_fax_cancel(struct ast_fax_session *s);
00079 static int spandsp_fax_switch_to_t38(struct ast_fax_session *s);
00080 static int spandsp_fax_gateway_start(struct ast_fax_session *s);
00081 static int spandsp_fax_gateway_process(struct ast_fax_session *s, const struct ast_frame *f);
00082 static void spandsp_fax_gateway_cleanup(struct ast_fax_session *s);
00083 static int spandsp_v21_detect(struct ast_fax_session *s, const struct ast_frame *f);
00084 static void spandsp_v21_cleanup(struct ast_fax_session *s);
00085 static void spandsp_v21_tone(void *data, int code, int level, int delay);
00086
00087 static char *spandsp_fax_cli_show_capabilities(int fd);
00088 static char *spandsp_fax_cli_show_session(struct ast_fax_session *s, int fd);
00089 static char *spandsp_fax_cli_show_stats(int fd);
00090 static char *spandsp_fax_cli_show_settings(int fd);
00091
00092 static struct ast_fax_tech spandsp_fax_tech = {
00093 .type = "Spandsp",
00094 .description = "Spandsp FAX Driver",
00095 #if SPANDSP_RELEASE_DATE >= 20090220
00096
00097 .version = SPANDSP_RELEASE_DATETIME_STRING,
00098 #else
00099
00100
00101
00102 .version = "pre-20090220",
00103 #endif
00104 .caps = AST_FAX_TECH_AUDIO | AST_FAX_TECH_T38 | AST_FAX_TECH_SEND
00105 | AST_FAX_TECH_RECEIVE | AST_FAX_TECH_GATEWAY
00106 | AST_FAX_TECH_V21_DETECT,
00107 .new_session = spandsp_fax_new,
00108 .destroy_session = spandsp_fax_destroy,
00109 .read = spandsp_fax_read,
00110 .write = spandsp_fax_write,
00111 .start_session = spandsp_fax_start,
00112 .cancel_session = spandsp_fax_cancel,
00113 .switch_to_t38 = spandsp_fax_switch_to_t38,
00114 .cli_show_capabilities = spandsp_fax_cli_show_capabilities,
00115 .cli_show_session = spandsp_fax_cli_show_session,
00116 .cli_show_stats = spandsp_fax_cli_show_stats,
00117 .cli_show_settings = spandsp_fax_cli_show_settings,
00118 };
00119
00120 struct spandsp_fax_stats {
00121 int success;
00122 int nofax;
00123 int neg_failed;
00124 int failed_to_train;
00125 int rx_protocol_error;
00126 int tx_protocol_error;
00127 int protocol_error;
00128 int retries_exceeded;
00129 int file_error;
00130 int mem_error;
00131 int call_dropped;
00132 int unknown_error;
00133 int switched;
00134 };
00135
00136 static struct {
00137 ast_mutex_t lock;
00138 struct spandsp_fax_stats g711;
00139 struct spandsp_fax_stats t38;
00140 } spandsp_global_stats;
00141
00142 struct spandsp_pvt {
00143 unsigned int ist38:1;
00144 unsigned int isdone:1;
00145 enum ast_t38_state ast_t38_state;
00146 fax_state_t fax_state;
00147 t38_terminal_state_t t38_state;
00148 t30_state_t *t30_state;
00149 t38_core_state_t *t38_core_state;
00150
00151 struct spandsp_fax_stats *stats;
00152
00153 struct spandsp_fax_gw_stats *t38stats;
00154 t38_gateway_state_t t38_gw_state;
00155
00156 struct ast_timer *timer;
00157 AST_LIST_HEAD(frame_queue, ast_frame) read_frames;
00158
00159 int v21_detected;
00160 modem_connect_tones_rx_state_t *tone_state;
00161 };
00162
00163 static int spandsp_v21_new(struct spandsp_pvt *p);
00164 static void session_destroy(struct spandsp_pvt *p);
00165 static int t38_tx_packet_handler(t38_core_state_t *t38_core_state, void *data, const uint8_t *buf, int len, int count);
00166 static void t30_phase_e_handler(t30_state_t *t30_state, void *data, int completion_code);
00167 static void spandsp_log(int level, const char *msg);
00168 static int update_stats(struct spandsp_pvt *p, int completion_code);
00169 static int spandsp_modems(struct ast_fax_session_details *details);
00170
00171 static void set_logging(logging_state_t *state, struct ast_fax_session_details *details);
00172 static void set_local_info(t30_state_t *t30_state, struct ast_fax_session_details *details);
00173 static void set_file(t30_state_t *t30_state, struct ast_fax_session_details *details);
00174 static void set_ecm(t30_state_t *t30_state, struct ast_fax_session_details *details);
00175
00176 static void session_destroy(struct spandsp_pvt *p)
00177 {
00178 struct ast_frame *f;
00179
00180 t30_terminate(p->t30_state);
00181 p->isdone = 1;
00182
00183 ast_timer_close(p->timer);
00184
00185 fax_release(&p->fax_state);
00186 t38_terminal_release(&p->t38_state);
00187
00188 while ((f = AST_LIST_REMOVE_HEAD(&p->read_frames, frame_list))) {
00189 ast_frfree(f);
00190 }
00191 }
00192
00193
00194
00195
00196 static int t38_tx_packet_handler(t38_core_state_t *t38_core_state, void *data, const uint8_t *buf, int len, int count)
00197 {
00198 int res = -1;
00199 struct ast_fax_session *s = data;
00200 struct spandsp_pvt *p = s->tech_pvt;
00201 struct ast_frame fax_frame = {
00202 .frametype = AST_FRAME_MODEM,
00203 .subclass.integer = AST_MODEM_T38,
00204 .src = "res_fax_spandsp_t38",
00205 };
00206
00207 struct ast_frame *f = &fax_frame;
00208
00209
00210
00211
00212
00213 AST_FRAME_SET_BUFFER(f, buf, 0, len);
00214
00215 if (!(f = ast_frisolate(f))) {
00216 return res;
00217 }
00218
00219 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
00220 ast_set_flag(f, AST_FAX_FRFLAG_GATEWAY);
00221 if (p->ast_t38_state == T38_STATE_NEGOTIATED) {
00222 res = ast_write(s->chan, f);
00223 } else {
00224 res = ast_queue_frame(s->chan, f);
00225 }
00226 ast_frfree(f);
00227 } else {
00228
00229 AST_LIST_INSERT_TAIL(&p->read_frames, f, frame_list);
00230 }
00231
00232 return res;
00233 }
00234
00235 static int update_stats(struct spandsp_pvt *p, int completion_code)
00236 {
00237 switch (completion_code) {
00238 case T30_ERR_OK:
00239 ast_atomic_fetchadd_int(&p->stats->success, 1);
00240 break;
00241
00242
00243 case T30_ERR_CEDTONE:
00244 case T30_ERR_T0_EXPIRED:
00245 case T30_ERR_T1_EXPIRED:
00246 case T30_ERR_T3_EXPIRED:
00247 case T30_ERR_HDLC_CARRIER:
00248 case T30_ERR_CANNOT_TRAIN:
00249 ast_atomic_fetchadd_int(&p->stats->failed_to_train, 1);
00250 break;
00251
00252 case T30_ERR_OPER_INT_FAIL:
00253 case T30_ERR_INCOMPATIBLE:
00254 case T30_ERR_RX_INCAPABLE:
00255 case T30_ERR_TX_INCAPABLE:
00256 case T30_ERR_NORESSUPPORT:
00257 case T30_ERR_NOSIZESUPPORT:
00258 ast_atomic_fetchadd_int(&p->stats->neg_failed, 1);
00259 break;
00260
00261 case T30_ERR_UNEXPECTED:
00262 ast_atomic_fetchadd_int(&p->stats->protocol_error, 1);
00263 break;
00264
00265
00266 case T30_ERR_TX_BADDCS:
00267 case T30_ERR_TX_BADPG:
00268 case T30_ERR_TX_ECMPHD:
00269 case T30_ERR_TX_GOTDCN:
00270 case T30_ERR_TX_INVALRSP:
00271 case T30_ERR_TX_NODIS:
00272 case T30_ERR_TX_PHBDEAD:
00273 case T30_ERR_TX_PHDDEAD:
00274 case T30_ERR_TX_T5EXP:
00275 ast_atomic_fetchadd_int(&p->stats->tx_protocol_error, 1);
00276 break;
00277
00278
00279 case T30_ERR_RX_ECMPHD:
00280 case T30_ERR_RX_GOTDCS:
00281 case T30_ERR_RX_INVALCMD:
00282 case T30_ERR_RX_NOCARRIER:
00283 case T30_ERR_RX_NOEOL:
00284 ast_atomic_fetchadd_int(&p->stats->rx_protocol_error, 1);
00285 break;
00286 case T30_ERR_RX_NOFAX:
00287 ast_atomic_fetchadd_int(&p->stats->nofax, 1);
00288 break;
00289 case T30_ERR_RX_T2EXPDCN:
00290 case T30_ERR_RX_T2EXPD:
00291 case T30_ERR_RX_T2EXPFAX:
00292 case T30_ERR_RX_T2EXPMPS:
00293 case T30_ERR_RX_T2EXPRR:
00294 case T30_ERR_RX_T2EXP:
00295 case T30_ERR_RX_DCNWHY:
00296 case T30_ERR_RX_DCNDATA:
00297 case T30_ERR_RX_DCNFAX:
00298 case T30_ERR_RX_DCNPHD:
00299 case T30_ERR_RX_DCNRRD:
00300 case T30_ERR_RX_DCNNORTN:
00301 ast_atomic_fetchadd_int(&p->stats->rx_protocol_error, 1);
00302 break;
00303
00304
00305 case T30_ERR_FILEERROR:
00306 case T30_ERR_NOPAGE:
00307 case T30_ERR_BADTIFF:
00308 case T30_ERR_BADPAGE:
00309 case T30_ERR_BADTAG:
00310 case T30_ERR_BADTIFFHDR:
00311 ast_atomic_fetchadd_int(&p->stats->file_error, 1);
00312 break;
00313 case T30_ERR_NOMEM:
00314 ast_atomic_fetchadd_int(&p->stats->mem_error, 1);
00315 break;
00316
00317
00318 case T30_ERR_RETRYDCN:
00319 ast_atomic_fetchadd_int(&p->stats->retries_exceeded, 1);
00320 break;
00321 case T30_ERR_CALLDROPPED:
00322 ast_atomic_fetchadd_int(&p->stats->call_dropped, 1);
00323 break;
00324
00325
00326 case T30_ERR_NOPOLL:
00327 case T30_ERR_IDENT_UNACCEPTABLE:
00328 case T30_ERR_SUB_UNACCEPTABLE:
00329 case T30_ERR_SEP_UNACCEPTABLE:
00330 case T30_ERR_PSA_UNACCEPTABLE:
00331 case T30_ERR_SID_UNACCEPTABLE:
00332 case T30_ERR_PWD_UNACCEPTABLE:
00333 case T30_ERR_TSA_UNACCEPTABLE:
00334 case T30_ERR_IRA_UNACCEPTABLE:
00335 case T30_ERR_CIA_UNACCEPTABLE:
00336 case T30_ERR_ISP_UNACCEPTABLE:
00337 case T30_ERR_CSA_UNACCEPTABLE:
00338 ast_atomic_fetchadd_int(&p->stats->neg_failed, 1);
00339 break;
00340 default:
00341 ast_atomic_fetchadd_int(&p->stats->unknown_error, 1);
00342 ast_log(LOG_WARNING, "unknown FAX session result '%d' (%s)\n", completion_code, t30_completion_code_to_str(completion_code));
00343 return -1;
00344 }
00345 return 0;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 static void t30_phase_e_handler(t30_state_t *t30_state, void *data, int completion_code)
00357 {
00358 struct ast_fax_session *s = data;
00359 struct spandsp_pvt *p = s->tech_pvt;
00360 char headerinfo[T30_MAX_PAGE_HEADER_INFO + 1];
00361 const char *c;
00362 t30_stats_t stats;
00363
00364 ast_debug(5, "FAX session '%d' entering phase E\n", s->id);
00365
00366 p->isdone = 1;
00367
00368 update_stats(p, completion_code);
00369
00370 t30_get_transfer_statistics(t30_state, &stats);
00371
00372 if (completion_code == T30_ERR_OK) {
00373 ast_string_field_set(s->details, result, "SUCCESS");
00374 } else {
00375 ast_string_field_set(s->details, result, "FAILED");
00376 ast_string_field_set(s->details, error, t30_completion_code_to_str(completion_code));
00377 }
00378
00379 ast_string_field_set(s->details, resultstr, t30_completion_code_to_str(completion_code));
00380
00381 ast_debug(5, "FAX session '%d' completed with result: %s (%s)\n", s->id, s->details->result, s->details->resultstr);
00382
00383 if ((c = t30_get_tx_ident(t30_state))) {
00384 ast_string_field_set(s->details, localstationid, c);
00385 }
00386
00387 if ((c = t30_get_rx_ident(t30_state))) {
00388 ast_string_field_set(s->details, remotestationid, c);
00389 }
00390
00391 #if SPANDSP_RELEASE_DATE >= 20090220
00392 s->details->pages_transferred = (s->details->caps & AST_FAX_TECH_RECEIVE) ? stats.pages_rx : stats.pages_tx;
00393 #else
00394 s->details->pages_transferred = stats.pages_transferred;
00395 #endif
00396
00397 ast_string_field_build(s->details, transfer_rate, "%d", stats.bit_rate);
00398
00399 ast_string_field_build(s->details, resolution, "%dx%d", stats.x_resolution, stats.y_resolution);
00400
00401 t30_get_tx_page_header_info(t30_state, headerinfo);
00402 ast_string_field_set(s->details, headerinfo, headerinfo);
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 static void spandsp_log(int level, const char *msg)
00412 {
00413 if (level == SPAN_LOG_ERROR) {
00414 ast_log(LOG_ERROR, "%s", msg);
00415 } else if (level == SPAN_LOG_WARNING) {
00416 ast_log(LOG_WARNING, "%s", msg);
00417 } else {
00418 ast_fax_log(LOG_DEBUG, msg);
00419 }
00420 }
00421
00422 static void set_logging(logging_state_t *state, struct ast_fax_session_details *details)
00423 {
00424 int level = SPAN_LOG_WARNING;
00425
00426 if (details->option.debug) {
00427 level = SPAN_LOG_DEBUG_3;
00428 }
00429
00430 span_log_set_message_handler(state, spandsp_log);
00431 span_log_set_level(state, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | level);
00432 }
00433
00434 static void set_local_info(t30_state_t *t30_state, struct ast_fax_session_details *details)
00435 {
00436 if (!ast_strlen_zero(details->localstationid)) {
00437 t30_set_tx_ident(t30_state, details->localstationid);
00438 }
00439
00440 if (!ast_strlen_zero(details->headerinfo)) {
00441 t30_set_tx_page_header_info(t30_state, details->headerinfo);
00442 }
00443 }
00444
00445 static void set_file(t30_state_t *t30_state, struct ast_fax_session_details *details)
00446 {
00447 if (details->caps & AST_FAX_TECH_RECEIVE) {
00448 t30_set_rx_file(t30_state, AST_LIST_FIRST(&details->documents)->filename, -1);
00449 } else {
00450
00451
00452
00453 t30_set_tx_file(t30_state, AST_LIST_FIRST(&details->documents)->filename, -1, -1);
00454 }
00455 }
00456
00457 static void set_ecm(t30_state_t *t30_state, struct ast_fax_session_details *details)
00458 {
00459 t30_set_ecm_capability(t30_state, details->option.ecm);
00460 t30_set_supported_compressions(t30_state, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
00461 }
00462
00463 static int spandsp_v21_new(struct spandsp_pvt *p)
00464 {
00465
00466
00467
00468
00469 p->tone_state = modem_connect_tones_rx_init(NULL, MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE, spandsp_v21_tone, p);
00470 if (!p->tone_state) {
00471 return -1;
00472 }
00473
00474 return 0;
00475 }
00476
00477 static int spandsp_modems(struct ast_fax_session_details *details)
00478 {
00479 int modems = 0;
00480 if (AST_FAX_MODEM_V17 & details->modems) {
00481 modems |= T30_SUPPORT_V17;
00482 }
00483 if (AST_FAX_MODEM_V27 & details->modems) {
00484 modems |= T30_SUPPORT_V27TER;
00485 }
00486 if (AST_FAX_MODEM_V29 & details->modems) {
00487 modems |= T30_SUPPORT_V29;
00488 }
00489 if (AST_FAX_MODEM_V34 & details->modems) {
00490 #if defined(T30_SUPPORT_V34)
00491 modems |= T30_SUPPORT_V34;
00492 #elif defined(T30_SUPPORT_V34HDX)
00493 modems |= T30_SUPPORT_V34HDX;
00494 #else
00495 ast_log(LOG_WARNING, "v34 not supported in this version of spandsp\n");
00496 #endif
00497 }
00498
00499 return modems;
00500 }
00501
00502
00503 static void *spandsp_fax_new(struct ast_fax_session *s, struct ast_fax_tech_token *token)
00504 {
00505 struct spandsp_pvt *p;
00506 int caller_mode;
00507
00508 if ((!(p = ast_calloc(1, sizeof(*p))))) {
00509 ast_log(LOG_ERROR, "Cannot initialize the spandsp private FAX technology structure.\n");
00510 goto e_return;
00511 }
00512
00513 if (s->details->caps & AST_FAX_TECH_V21_DETECT) {
00514 if (spandsp_v21_new(p)) {
00515 ast_log(LOG_ERROR, "Cannot initialize the spandsp private v21 technology structure.\n");
00516 goto e_return;
00517 }
00518 s->state = AST_FAX_STATE_ACTIVE;
00519 return p;
00520 }
00521
00522 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
00523 s->state = AST_FAX_STATE_INITIALIZED;
00524 return p;
00525 }
00526
00527 AST_LIST_HEAD_INIT(&p->read_frames);
00528
00529 if (s->details->caps & AST_FAX_TECH_RECEIVE) {
00530 caller_mode = 0;
00531 } else if (s->details->caps & AST_FAX_TECH_SEND) {
00532 caller_mode = 1;
00533 } else {
00534 ast_log(LOG_ERROR, "Are we sending or receiving? The FAX requirements (capabilities: 0x%X) were not properly set.\n", s->details->caps);
00535 goto e_free;
00536 }
00537
00538 if (!(p->timer = ast_timer_open())) {
00539 ast_log(LOG_ERROR, "Channel '%s' FAX session '%d' failed to create timing source.\n", s->channame, s->id);
00540 goto e_free;
00541 }
00542
00543 s->fd = ast_timer_fd(p->timer);
00544
00545 p->stats = &spandsp_global_stats.g711;
00546
00547 if (s->details->caps & AST_FAX_TECH_T38) {
00548 if ((s->details->caps & AST_FAX_TECH_AUDIO) == 0) {
00549
00550 p->ist38 = 1;
00551 p->stats = &spandsp_global_stats.t38;
00552 }
00553
00554
00555 t38_terminal_init(&p->t38_state, caller_mode, t38_tx_packet_handler, s);
00556 set_logging(&p->t38_state.logging, s->details);
00557 }
00558
00559 if (s->details->caps & AST_FAX_TECH_AUDIO) {
00560
00561 fax_init(&p->fax_state, caller_mode);
00562 set_logging(&p->fax_state.logging, s->details);
00563 }
00564
00565 s->state = AST_FAX_STATE_INITIALIZED;
00566 return p;
00567
00568 e_free:
00569 ast_free(p);
00570 e_return:
00571 return NULL;
00572 }
00573
00574 static void spandsp_v21_cleanup(struct ast_fax_session *s) {
00575 struct spandsp_pvt *p = s->tech_pvt;
00576 modem_connect_tones_rx_free(p->tone_state);
00577 }
00578
00579
00580
00581 static void spandsp_fax_destroy(struct ast_fax_session *s)
00582 {
00583 struct spandsp_pvt *p = s->tech_pvt;
00584
00585 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
00586 spandsp_fax_gateway_cleanup(s);
00587 } else if (s->details->caps & AST_FAX_TECH_V21_DETECT) {
00588 spandsp_v21_cleanup(s);
00589 } else {
00590 session_destroy(p);
00591 }
00592
00593 ast_free(p);
00594 s->tech_pvt = NULL;
00595 s->fd = -1;
00596 }
00597
00598
00599
00600 static struct ast_frame *spandsp_fax_read(struct ast_fax_session *s)
00601 {
00602 struct spandsp_pvt *p = s->tech_pvt;
00603 uint8_t buffer[AST_FRIENDLY_OFFSET + SPANDSP_FAX_SAMPLES * sizeof(uint16_t)];
00604 int16_t *buf = (int16_t *) (buffer + AST_FRIENDLY_OFFSET);
00605 int samples;
00606
00607 struct ast_frame fax_frame = {
00608 .frametype = AST_FRAME_VOICE,
00609 .src = "res_fax_spandsp_g711",
00610 };
00611 struct ast_frame *f = &fax_frame;
00612 ast_format_set(&fax_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
00613
00614 ast_timer_ack(p->timer, 1);
00615
00616
00617 if (p->isdone) {
00618 s->state = AST_FAX_STATE_COMPLETE;
00619 ast_debug(5, "FAX session '%d' is complete.\n", s->id);
00620 return NULL;
00621 }
00622
00623 if (p->ist38) {
00624 t38_terminal_send_timeout(&p->t38_state, SPANDSP_FAX_SAMPLES);
00625 if ((f = AST_LIST_REMOVE_HEAD(&p->read_frames, frame_list))) {
00626 return f;
00627 }
00628 } else {
00629 if ((samples = fax_tx(&p->fax_state, buf, SPANDSP_FAX_SAMPLES)) > 0) {
00630 f->samples = samples;
00631 AST_FRAME_SET_BUFFER(f, buffer, AST_FRIENDLY_OFFSET, samples * sizeof(int16_t));
00632 return ast_frisolate(f);
00633 }
00634 }
00635
00636 return &ast_null_frame;
00637 }
00638
00639 static void spandsp_v21_tone(void *data, int code, int level, int delay)
00640 {
00641 struct spandsp_pvt *p = data;
00642
00643 if (code == MODEM_CONNECT_TONES_FAX_PREAMBLE) {
00644 p->v21_detected = 1;
00645 }
00646 }
00647
00648 static int spandsp_v21_detect(struct ast_fax_session *s, const struct ast_frame *f) {
00649 struct spandsp_pvt *p = s->tech_pvt;
00650
00651 if (p->v21_detected) {
00652 return 0;
00653 }
00654
00655
00656 if (!f->data.ptr || !f->datalen) {
00657 return -1;
00658 }
00659
00660 modem_connect_tones_rx(p->tone_state, f->data.ptr, f->samples);
00661
00662 if (p->v21_detected) {
00663 s->details->option.v21_detected = 1;
00664 }
00665
00666 return 0;
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 static int spandsp_fax_write(struct ast_fax_session *s, const struct ast_frame *f)
00680 {
00681 struct spandsp_pvt *p = s->tech_pvt;
00682
00683 if (s->details->caps & AST_FAX_TECH_V21_DETECT) {
00684 return spandsp_v21_detect(s, f);
00685 }
00686
00687 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
00688 return spandsp_fax_gateway_process(s, f);
00689 }
00690
00691
00692 if (s->state == AST_FAX_STATE_COMPLETE) {
00693 ast_log(LOG_WARNING, "FAX session '%d' is in the '%s' state.\n", s->id, ast_fax_state_to_str(s->state));
00694 return -1;
00695 }
00696
00697 if (p->ist38) {
00698 return t38_core_rx_ifp_packet(p->t38_core_state, f->data.ptr, f->datalen, f->seqno);
00699 } else {
00700 return fax_rx(&p->fax_state, f->data.ptr, f->samples);
00701 }
00702 }
00703
00704
00705
00706
00707
00708
00709
00710 static int spandsp_fax_gw_t30_gen(struct ast_channel *chan, void *data, int len, int samples)
00711 {
00712 int res = -1;
00713 struct ast_fax_session *s = data;
00714 struct spandsp_pvt *p = s->tech_pvt;
00715 uint8_t buffer[AST_FRIENDLY_OFFSET + samples * sizeof(uint16_t)];
00716 struct ast_frame *f;
00717 struct ast_frame t30_frame = {
00718 .frametype = AST_FRAME_VOICE,
00719 .src = "res_fax_spandsp_g711",
00720 .samples = samples,
00721 .flags = AST_FAX_FRFLAG_GATEWAY,
00722 };
00723
00724 AST_FRAME_SET_BUFFER(&t30_frame, buffer, AST_FRIENDLY_OFFSET, t30_frame.samples * sizeof(int16_t));
00725
00726 ast_format_set(&t30_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
00727 if (!(f = ast_frisolate(&t30_frame))) {
00728 return p->isdone ? -1 : res;
00729 }
00730
00731
00732 if ((f->samples = t38_gateway_tx(&p->t38_gw_state, f->data.ptr, f->samples))) {
00733 f->datalen = f->samples * sizeof(int16_t);
00734 res = ast_write(chan, f);
00735 }
00736 ast_frfree(f);
00737 return p->isdone ? -1 : res;
00738 }
00739
00740
00741
00742
00743
00744 static void *spandsp_fax_gw_gen_alloc(struct ast_channel *chan, void *params) {
00745 ao2_ref(params, +1);
00746 return params;
00747 }
00748
00749 static void spandsp_fax_gw_gen_release(struct ast_channel *chan, void *data) {
00750 ao2_ref(data, -1);
00751 }
00752
00753
00754
00755
00756 static int spandsp_fax_gateway_start(struct ast_fax_session *s) {
00757 struct spandsp_pvt *p = s->tech_pvt;
00758 struct ast_fax_t38_parameters *t38_param;
00759 int i;
00760 struct ast_channel *peer;
00761 static struct ast_generator t30_gen = {
00762 .alloc = spandsp_fax_gw_gen_alloc,
00763 .release = spandsp_fax_gw_gen_release,
00764 .generate = spandsp_fax_gw_t30_gen,
00765 };
00766
00767 #if SPANDSP_RELEASE_DATE >= 20081012
00768
00769 p->t38_core_state=&p->t38_gw_state.t38x.t38;
00770 #else
00771
00772 p->t38_core_state=&p->t38_gw_state.t38;
00773 #endif
00774
00775 if (!t38_gateway_init(&p->t38_gw_state, t38_tx_packet_handler, s)) {
00776 return -1;
00777 }
00778
00779 p->ist38 = 1;
00780 p->ast_t38_state = ast_channel_get_t38_state(s->chan);
00781 if (!(peer = ast_bridged_channel(s->chan))) {
00782 ast_channel_unlock(s->chan);
00783 return -1;
00784 }
00785
00786
00787
00788 if (p->ast_t38_state == T38_STATE_NEGOTIATING) {
00789 p->ast_t38_state = T38_STATE_NEGOTIATED;
00790 }
00791
00792 ast_activate_generator(p->ast_t38_state == T38_STATE_NEGOTIATED ? peer : s->chan, &t30_gen , s);
00793
00794 set_logging(&p->t38_gw_state.logging, s->details);
00795 set_logging(&p->t38_core_state->logging, s->details);
00796
00797 t38_param = (p->ast_t38_state == T38_STATE_NEGOTIATED) ? &s->details->our_t38_parameters : &s->details->their_t38_parameters;
00798 t38_set_t38_version(p->t38_core_state, t38_param->version);
00799 t38_gateway_set_ecm_capability(&p->t38_gw_state, s->details->option.ecm);
00800 t38_set_max_datagram_size(p->t38_core_state, t38_param->max_ifp);
00801 t38_set_fill_bit_removal(p->t38_core_state, t38_param->fill_bit_removal);
00802 t38_set_mmr_transcoding(p->t38_core_state, t38_param->transcoding_mmr);
00803 t38_set_jbig_transcoding(p->t38_core_state, t38_param->transcoding_jbig);
00804 t38_set_data_rate_management_method(p->t38_core_state,
00805 (t38_param->rate_management == AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF)? 1 : 2);
00806
00807 t38_gateway_set_transmit_on_idle(&p->t38_gw_state, TRUE);
00808 t38_set_sequence_number_handling(p->t38_core_state, TRUE);
00809
00810
00811 t38_gateway_set_supported_modems(&p->t38_gw_state, spandsp_modems(s->details));
00812
00813
00814
00815
00816
00817 for (i=0; i < SPANDSP_ENGAGE_UDPTL_NAT_RETRY; i++) {
00818 #if SPANDSP_RELEASE_DATE >= 20091228
00819 t38_core_send_indicator(&p->t38_gw_state.t38x.t38, T38_IND_NO_SIGNAL);
00820 #elif SPANDSP_RELEASE_DATE >= 20081012
00821 t38_core_send_indicator(&p->t38_gw_state.t38x.t38, T38_IND_NO_SIGNAL, p->t38_gw_state.t38x.t38.indicator_tx_count);
00822 #else
00823 t38_core_send_indicator(&p->t38_gw_state.t38, T38_IND_NO_SIGNAL, p->t38_gw_state.t38.indicator_tx_count);
00824 #endif
00825 }
00826
00827 s->state = AST_FAX_STATE_ACTIVE;
00828
00829 return 0;
00830 }
00831
00832
00833
00834
00835
00836 static int spandsp_fax_gateway_process(struct ast_fax_session *s, const struct ast_frame *f)
00837 {
00838 struct spandsp_pvt *p = s->tech_pvt;
00839
00840
00841 if (!f->data.ptr || !f->datalen) {
00842 return -1;
00843 }
00844
00845
00846 if ((f->frametype == AST_FRAME_MODEM) && (f->subclass.integer == AST_MODEM_T38)) {
00847 return t38_core_rx_ifp_packet(p->t38_core_state, f->data.ptr, f->datalen, f->seqno);
00848 } else if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id == AST_FORMAT_SLINEAR)) {
00849 return t38_gateway_rx(&p->t38_gw_state, f->data.ptr, f->samples);
00850 }
00851
00852 return -1;
00853 }
00854
00855
00856
00857 static void spandsp_fax_gateway_cleanup(struct ast_fax_session *s)
00858 {
00859 struct spandsp_pvt *p = s->tech_pvt;
00860 t38_stats_t t38_stats;
00861
00862 t38_gateway_get_transfer_statistics(&p->t38_gw_state, &t38_stats);
00863
00864 s->details->option.ecm = t38_stats.error_correcting_mode ? AST_FAX_OPTFLAG_TRUE : AST_FAX_OPTFLAG_FALSE;
00865 s->details->pages_transferred = t38_stats.pages_transferred;
00866 ast_string_field_build(s->details, transfer_rate, "%d", t38_stats.bit_rate);
00867 }
00868
00869
00870 static int spandsp_fax_start(struct ast_fax_session *s)
00871 {
00872 struct spandsp_pvt *p = s->tech_pvt;
00873
00874 s->state = AST_FAX_STATE_OPEN;
00875
00876 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
00877 return spandsp_fax_gateway_start(s);
00878 }
00879
00880 if (p->ist38) {
00881 #if SPANDSP_RELEASE_DATE >= 20080725
00882
00883 p->t30_state = &p->t38_state.t30;
00884 p->t38_core_state = &p->t38_state.t38_fe.t38;
00885 #else
00886
00887 p->t30_state = &p->t38_state.t30_state;
00888 p->t38_core_state = &p->t38_state.t38;
00889 #endif
00890 } else {
00891 #if SPANDSP_RELEASE_DATE >= 20080725
00892
00893 p->t30_state = &p->fax_state.t30;
00894 #else
00895
00896 p->t30_state = &p->fax_state.t30_state;
00897 #endif
00898 }
00899
00900 set_logging(&p->t30_state->logging, s->details);
00901
00902
00903 set_local_info(p->t30_state, s->details);
00904 set_file(p->t30_state, s->details);
00905 set_ecm(p->t30_state, s->details);
00906 t30_set_supported_modems(p->t30_state, spandsp_modems(s->details));
00907
00908
00909
00910 t30_set_phase_e_handler(p->t30_state, t30_phase_e_handler, s);
00911
00912
00913 if (p->ist38) {
00914 set_logging(&p->t38_core_state->logging, s->details);
00915
00916 t38_set_max_datagram_size(p->t38_core_state, s->details->their_t38_parameters.max_ifp);
00917
00918 if (s->details->their_t38_parameters.fill_bit_removal) {
00919 t38_set_fill_bit_removal(p->t38_core_state, TRUE);
00920 }
00921
00922 if (s->details->their_t38_parameters.transcoding_mmr) {
00923 t38_set_mmr_transcoding(p->t38_core_state, TRUE);
00924 }
00925
00926 if (s->details->their_t38_parameters.transcoding_jbig) {
00927 t38_set_jbig_transcoding(p->t38_core_state, TRUE);
00928 }
00929 } else {
00930
00931 fax_set_transmit_on_idle(&p->fax_state, 1);
00932 }
00933
00934
00935
00936 if (ast_timer_set_rate(p->timer, SPANDSP_FAX_TIMER_RATE)) {
00937 ast_log(LOG_ERROR, "FAX session '%d' error setting rate on timing source.\n", s->id);
00938 return -1;
00939 }
00940
00941 s->state = AST_FAX_STATE_ACTIVE;
00942
00943 return 0;
00944 }
00945
00946
00947 static int spandsp_fax_cancel(struct ast_fax_session *s)
00948 {
00949 struct spandsp_pvt *p = s->tech_pvt;
00950
00951 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
00952 p->isdone = 1;
00953 return 0;
00954 }
00955
00956 t30_terminate(p->t30_state);
00957 p->isdone = 1;
00958 return 0;
00959 }
00960
00961
00962 static int spandsp_fax_switch_to_t38(struct ast_fax_session *s)
00963 {
00964 struct spandsp_pvt *p = s->tech_pvt;
00965
00966
00967 t30_set_phase_e_handler(p->t30_state, NULL, NULL);
00968
00969 t30_terminate(p->t30_state);
00970
00971 s->details->option.switch_to_t38 = 1;
00972 ast_atomic_fetchadd_int(&p->stats->switched, 1);
00973
00974 p->ist38 = 1;
00975 p->stats = &spandsp_global_stats.t38;
00976 spandsp_fax_start(s);
00977
00978 return 0;
00979 }
00980
00981
00982 static char *spandsp_fax_cli_show_capabilities(int fd)
00983 {
00984 ast_cli(fd, "SEND RECEIVE T.38 G.711 GATEWAY\n\n");
00985 return CLI_SUCCESS;
00986 }
00987
00988
00989 static char *spandsp_fax_cli_show_session(struct ast_fax_session *s, int fd)
00990 {
00991 ao2_lock(s);
00992 if (s->details->caps & AST_FAX_TECH_GATEWAY) {
00993 struct spandsp_pvt *p = s->tech_pvt;
00994
00995 ast_cli(fd, "%-22s : %d\n", "session", s->id);
00996 ast_cli(fd, "%-22s : %s\n", "operation", "Gateway");
00997 ast_cli(fd, "%-22s : %s\n", "state", ast_fax_state_to_str(s->state));
00998 if (s->state != AST_FAX_STATE_UNINITIALIZED) {
00999 t38_stats_t stats;
01000 t38_gateway_get_transfer_statistics(&p->t38_gw_state, &stats);
01001 ast_cli(fd, "%-22s : %s\n", "ECM Mode", stats.error_correcting_mode ? "Yes" : "No");
01002 ast_cli(fd, "%-22s : %d\n", "Data Rate", stats.bit_rate);
01003 ast_cli(fd, "%-22s : %d\n", "Page Number", stats.pages_transferred + 1);
01004 }
01005 } else if (s->details->caps & AST_FAX_TECH_V21_DETECT) {
01006 ast_cli(fd, "%-22s : %d\n", "session", s->id);
01007 ast_cli(fd, "%-22s : %s\n", "operation", "V.21 Detect");
01008 ast_cli(fd, "%-22s : %s\n", "state", ast_fax_state_to_str(s->state));
01009 } else {
01010 struct spandsp_pvt *p = s->tech_pvt;
01011
01012 ast_cli(fd, "%-22s : %d\n", "session", s->id);
01013 ast_cli(fd, "%-22s : %s\n", "operation", (s->details->caps & AST_FAX_TECH_RECEIVE) ? "Receive" : "Transmit");
01014 ast_cli(fd, "%-22s : %s\n", "state", ast_fax_state_to_str(s->state));
01015 if (s->state != AST_FAX_STATE_UNINITIALIZED) {
01016 t30_stats_t stats;
01017 t30_get_transfer_statistics(p->t30_state, &stats);
01018 ast_cli(fd, "%-22s : %s\n", "Last Status", t30_completion_code_to_str(stats.current_status));
01019 ast_cli(fd, "%-22s : %s\n", "ECM Mode", stats.error_correcting_mode ? "Yes" : "No");
01020 ast_cli(fd, "%-22s : %d\n", "Data Rate", stats.bit_rate);
01021 ast_cli(fd, "%-22s : %dx%d\n", "Image Resolution", stats.x_resolution, stats.y_resolution);
01022 #if SPANDSP_RELEASE_DATE >= 20090220
01023 ast_cli(fd, "%-22s : %d\n", "Page Number", ((s->details->caps & AST_FAX_TECH_RECEIVE) ? stats.pages_rx : stats.pages_tx) + 1);
01024 #else
01025 ast_cli(fd, "%-22s : %d\n", "Page Number", stats.pages_transferred + 1);
01026 #endif
01027 ast_cli(fd, "%-22s : %s\n", "File Name", s->details->caps & AST_FAX_TECH_RECEIVE ? p->t30_state->rx_file : p->t30_state->tx_file);
01028
01029 ast_cli(fd, "\nData Statistics:\n");
01030 #if SPANDSP_RELEASE_DATE >= 20090220
01031 ast_cli(fd, "%-22s : %d\n", "Tx Pages", stats.pages_tx);
01032 ast_cli(fd, "%-22s : %d\n", "Rx Pages", stats.pages_rx);
01033 #else
01034 ast_cli(fd, "%-22s : %d\n", "Tx Pages", (s->details->caps & AST_FAX_TECH_SEND) ? stats.pages_transferred : 0);
01035 ast_cli(fd, "%-22s : %d\n", "Rx Pages", (s->details->caps & AST_FAX_TECH_RECEIVE) ? stats.pages_transferred : 0);
01036 #endif
01037 ast_cli(fd, "%-22s : %d\n", "Longest Bad Line Run", stats.longest_bad_row_run);
01038 ast_cli(fd, "%-22s : %d\n", "Total Bad Lines", stats.bad_rows);
01039 }
01040 }
01041 ao2_unlock(s);
01042 ast_cli(fd, "\n\n");
01043 return CLI_SUCCESS;
01044 }
01045
01046
01047 static char *spandsp_fax_cli_show_stats(int fd)
01048 {
01049 ast_mutex_lock(&spandsp_global_stats.lock);
01050 ast_cli(fd, "\n%-20.20s\n", "Spandsp G.711");
01051 ast_cli(fd, "%-20.20s : %d\n", "Success", spandsp_global_stats.g711.success);
01052 ast_cli(fd, "%-20.20s : %d\n", "Switched to T.38", spandsp_global_stats.g711.switched);
01053 ast_cli(fd, "%-20.20s : %d\n", "Call Dropped", spandsp_global_stats.g711.call_dropped);
01054 ast_cli(fd, "%-20.20s : %d\n", "No FAX", spandsp_global_stats.g711.nofax);
01055 ast_cli(fd, "%-20.20s : %d\n", "Negotiation Failed", spandsp_global_stats.g711.neg_failed);
01056 ast_cli(fd, "%-20.20s : %d\n", "Train Failure", spandsp_global_stats.g711.failed_to_train);
01057 ast_cli(fd, "%-20.20s : %d\n", "Retries Exceeded", spandsp_global_stats.g711.retries_exceeded);
01058 ast_cli(fd, "%-20.20s : %d\n", "Protocol Error", spandsp_global_stats.g711.protocol_error);
01059 ast_cli(fd, "%-20.20s : %d\n", "TX Protocol Error", spandsp_global_stats.g711.tx_protocol_error);
01060 ast_cli(fd, "%-20.20s : %d\n", "RX Protocol Error", spandsp_global_stats.g711.rx_protocol_error);
01061 ast_cli(fd, "%-20.20s : %d\n", "File Error", spandsp_global_stats.g711.file_error);
01062 ast_cli(fd, "%-20.20s : %d\n", "Memory Error", spandsp_global_stats.g711.mem_error);
01063 ast_cli(fd, "%-20.20s : %d\n", "Unknown Error", spandsp_global_stats.g711.unknown_error);
01064
01065 ast_cli(fd, "\n%-20.20s\n", "Spandsp T.38");
01066 ast_cli(fd, "%-20.20s : %d\n", "Success", spandsp_global_stats.t38.success);
01067 ast_cli(fd, "%-20.20s : %d\n", "Call Dropped", spandsp_global_stats.t38.call_dropped);
01068 ast_cli(fd, "%-20.20s : %d\n", "No FAX", spandsp_global_stats.t38.nofax);
01069 ast_cli(fd, "%-20.20s : %d\n", "Negotiation Failed", spandsp_global_stats.t38.neg_failed);
01070 ast_cli(fd, "%-20.20s : %d\n", "Train Failure", spandsp_global_stats.t38.failed_to_train);
01071 ast_cli(fd, "%-20.20s : %d\n", "Retries Exceeded", spandsp_global_stats.t38.retries_exceeded);
01072 ast_cli(fd, "%-20.20s : %d\n", "Protocol Error", spandsp_global_stats.t38.protocol_error);
01073 ast_cli(fd, "%-20.20s : %d\n", "TX Protocol Error", spandsp_global_stats.t38.tx_protocol_error);
01074 ast_cli(fd, "%-20.20s : %d\n", "RX Protocol Error", spandsp_global_stats.t38.rx_protocol_error);
01075 ast_cli(fd, "%-20.20s : %d\n", "File Error", spandsp_global_stats.t38.file_error);
01076 ast_cli(fd, "%-20.20s : %d\n", "Memory Error", spandsp_global_stats.t38.mem_error);
01077 ast_cli(fd, "%-20.20s : %d\n", "Unknown Error", spandsp_global_stats.t38.unknown_error);
01078 ast_mutex_unlock(&spandsp_global_stats.lock);
01079
01080 return CLI_SUCCESS;
01081 }
01082
01083
01084 static char *spandsp_fax_cli_show_settings(int fd)
01085 {
01086
01087 return CLI_SUCCESS;
01088 }
01089
01090
01091 static int unload_module(void)
01092 {
01093 ast_fax_tech_unregister(&spandsp_fax_tech);
01094 ast_mutex_destroy(&spandsp_global_stats.lock);
01095 return AST_MODULE_LOAD_SUCCESS;
01096 }
01097
01098
01099 static int load_module(void)
01100 {
01101 ast_mutex_init(&spandsp_global_stats.lock);
01102 spandsp_fax_tech.module = ast_module_info->self;
01103 if (ast_fax_tech_register(&spandsp_fax_tech) < 0) {
01104 ast_log(LOG_ERROR, "failed to register FAX technology\n");
01105 return AST_MODULE_LOAD_DECLINE;
01106 }
01107
01108
01109 span_set_message_handler(NULL);
01110
01111 return AST_MODULE_LOAD_SUCCESS;
01112 }
01113
01114
01115 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Spandsp G.711 and T.38 FAX Technologies",
01116 .load = load_module,
01117 .unload = unload_module,
01118 );