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