|
|
|
@ -2921,6 +2921,9 @@ static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if we start gateway we don't need v21 detection sessions any more */
|
|
|
|
|
destroy_v21_sessions(gateway);
|
|
|
|
|
|
|
|
|
|
/* create the FAX session */
|
|
|
|
|
if (!(s = fax_session_new(details, chan, gateway->s, gateway->token))) {
|
|
|
|
|
gateway->token = NULL;
|
|
|
|
@ -2962,7 +2965,7 @@ static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! \pre chan is locked on entry */
|
|
|
|
|
static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan, struct ast_frame *f)
|
|
|
|
|
static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, struct ast_channel *chan)
|
|
|
|
|
{
|
|
|
|
|
struct ast_frame *fp;
|
|
|
|
|
struct ast_control_t38_parameters t38_parameters = {
|
|
|
|
@ -2981,7 +2984,7 @@ static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, st
|
|
|
|
|
if (!details) {
|
|
|
|
|
ast_log(LOG_ERROR, "no FAX session details found on chan %s for T.38 gateway session, odd\n", ast_channel_name(chan));
|
|
|
|
|
ast_framehook_detach(chan, gateway->framehook);
|
|
|
|
|
return f;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t38_parameters_fax_to_ast(&t38_parameters, &details->our_t38_parameters);
|
|
|
|
@ -2989,7 +2992,7 @@ static struct ast_frame *fax_gateway_request_t38(struct fax_gateway *gateway, st
|
|
|
|
|
|
|
|
|
|
if (!(fp = ast_frisolate(&control_frame))) {
|
|
|
|
|
ast_log(LOG_ERROR, "error generating T.38 request control frame on chan %s for T.38 gateway session\n", ast_channel_name(chan));
|
|
|
|
|
return f;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gateway->t38_state = T38_STATE_NEGOTIATING;
|
|
|
|
@ -3018,17 +3021,40 @@ static struct ast_frame *fax_gateway_detect_v21(struct fax_gateway *gateway, str
|
|
|
|
|
|
|
|
|
|
if (gateway->detected_v21) {
|
|
|
|
|
enum ast_t38_state state_other;
|
|
|
|
|
enum ast_t38_state state_active;
|
|
|
|
|
struct ast_frame *fp;
|
|
|
|
|
|
|
|
|
|
destroy_v21_sessions(gateway);
|
|
|
|
|
|
|
|
|
|
ast_channel_unlock(chan);
|
|
|
|
|
state_active = ast_channel_get_t38_state(active);
|
|
|
|
|
state_other = ast_channel_get_t38_state(other);
|
|
|
|
|
ast_channel_lock(chan);
|
|
|
|
|
if (state_other == T38_STATE_UNKNOWN) {
|
|
|
|
|
ast_debug(1, "detected v21 preamble from %s\n", ast_channel_name(active));
|
|
|
|
|
return fax_gateway_request_t38(gateway, chan, f);
|
|
|
|
|
|
|
|
|
|
ast_debug(1, "detected v21 preamble from %s\n", ast_channel_name(active));
|
|
|
|
|
|
|
|
|
|
if (state_active == T38_STATE_UNKNOWN || state_other == T38_STATE_UNKNOWN) {
|
|
|
|
|
if (!(fp = fax_gateway_request_t38(gateway, chan))) {
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
/* May be called endpoint is improperly configured to rely on the calling endpoint
|
|
|
|
|
* to initiate T.38 re-INVITEs, send T.38 negotiation request to called endpoint */
|
|
|
|
|
if (state_active == T38_STATE_UNKNOWN) {
|
|
|
|
|
ast_debug(1, "sending T.38 negotiation request to %s\n", ast_channel_name(active));
|
|
|
|
|
if (active == chan) {
|
|
|
|
|
ast_channel_unlock(chan);
|
|
|
|
|
}
|
|
|
|
|
ast_write(active, fp);
|
|
|
|
|
if (active == chan) {
|
|
|
|
|
ast_channel_lock(chan);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (state_other == T38_STATE_UNKNOWN) {
|
|
|
|
|
ast_debug(1, "sending T.38 negotiation request to %s\n", ast_channel_name(other));
|
|
|
|
|
return fp;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ast_debug(1, "detected v21 preamble on %s, but %s does not support T.38 for T.38 gateway session\n", ast_channel_name(active), ast_channel_name(other));
|
|
|
|
|
ast_debug(1, "neither %s nor %s support T.38 for T.38 gateway session\n", ast_channel_name(active), ast_channel_name(other));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -3190,7 +3216,7 @@ static struct ast_frame *fax_gateway_detect_t38(struct fax_gateway *gateway, str
|
|
|
|
|
ast_channel_lock(chan);
|
|
|
|
|
if (state_other == T38_STATE_UNKNOWN) {
|
|
|
|
|
gateway->t38_state = T38_STATE_UNAVAILABLE;
|
|
|
|
|
} else {
|
|
|
|
|
} else if (state_other != T38_STATE_NEGOTIATING) {
|
|
|
|
|
ast_framehook_detach(chan, details->gateway_id);
|
|
|
|
|
details->gateway_id = -1;
|
|
|
|
|
|
|
|
|
|