build: Update config.guess and config.sub
[asterisk/asterisk.git] / res / res_fax_spandsp.c
index 75018e8..045dbc7 100644 (file)
        <support_level>extended</support_level>
 ***/
 
+/* Needed for spandsp headers */
+#define ASTMM_LIBC ASTMM_IGNORE
 #include "asterisk.h"
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
-#include <spandsp.h>
-#include <spandsp/version.h>
-
 #include "asterisk/logger.h"
 #include "asterisk/module.h"
 #include "asterisk/strings.h"
@@ -65,6 +61,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/astobj2.h"
 #include "asterisk/res_fax.h"
 #include "asterisk/channel.h"
+#include "asterisk/format_cache.h"
+
+#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
+#include <spandsp.h>
+#include <spandsp/version.h>
 
 #define SPANDSP_FAX_SAMPLES 160
 #define SPANDSP_FAX_TIMER_RATE 8000 / SPANDSP_FAX_SAMPLES      /* 50 ticks per second, 20ms, 160 samples per second */
@@ -179,8 +180,25 @@ static void set_ecm(t30_state_t *t30_state, struct ast_fax_session_details *deta
 static void session_destroy(struct spandsp_pvt *p)
 {
        struct ast_frame *f;
+       t30_state_t *t30_to_terminate;
 
-       t30_terminate(p->t30_state);
+       if (p->t30_state) {
+               t30_to_terminate = p->t30_state;
+       } else if (p->ist38) {
+#if SPANDSP_RELEASE_DATE >= 20080725
+               t30_to_terminate = &p->t38_state.t30;
+#else
+               t30_to_terminate = &p->t38_state.t30_state;
+#endif
+       } else {
+#if SPANDSP_RELEASE_DATE >= 20080725
+               t30_to_terminate = &p->fax_state.t30;
+#else
+               t30_to_terminate = &p->fax_state.t30_state;
+#endif
+       }
+
+       t30_terminate(t30_to_terminate);
        p->isdone = 1;
 
        ast_timer_close(p->timer);
@@ -484,7 +502,7 @@ static int spandsp_modems(struct ast_fax_session_details *details)
        if (AST_FAX_MODEM_V17 & details->modems) {
                modems |= T30_SUPPORT_V17;
        }
-       if (AST_FAX_MODEM_V27 & details->modems) {
+       if (AST_FAX_MODEM_V27TER & details->modems) {
                modems |= T30_SUPPORT_V27TER;
        }
        if (AST_FAX_MODEM_V29 & details->modems) {
@@ -573,8 +591,10 @@ e_return:
        return NULL;
 }
 
-static void spandsp_v21_cleanup(struct ast_fax_session *s) {
+static void spandsp_v21_cleanup(struct ast_fax_session *s)
+{
        struct spandsp_pvt *p = s->tech_pvt;
+
        modem_connect_tones_rx_free(p->tone_state);
 }
 
@@ -609,9 +629,9 @@ static struct ast_frame *spandsp_fax_read(struct ast_fax_session *s)
        struct ast_frame fax_frame = {
                .frametype = AST_FRAME_VOICE,
                .src = "res_fax_spandsp_g711",
+               .subclass.format = ast_format_slin,
        };
        struct ast_frame *f = &fax_frame;
-       ast_format_set(&fax_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
 
        if (ast_timer_ack(p->timer, 1) < 0) {
                ast_log(LOG_ERROR, "Failed to acknowledge timer for FAX session '%u'\n", s->id);
@@ -650,7 +670,8 @@ static void spandsp_v21_tone(void *data, int code, int level, int delay)
        }
 }
 
-static int spandsp_v21_detect(struct ast_fax_session *s, const struct ast_frame *f) {
+static int spandsp_v21_detect(struct ast_fax_session *s, const struct ast_frame *f)
+{
        struct spandsp_pvt *p = s->tech_pvt;
        int16_t *slndata;
        g711_state_t *decoder;
@@ -664,20 +685,21 @@ static int spandsp_v21_detect(struct ast_fax_session *s, const struct ast_frame
                return -1;
        }
 
-       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.id=%u  }\n", f->datalen, f->samples, f->mallocd, f->src, f->flags, f->ts, f->len, f->seqno, f->data.ptr, f->subclass.format.id);
+       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));
 
        /* slinear frame can be passed to spandsp */
-       if (f->subclass.format.id == AST_FORMAT_SLINEAR) {
+       if (ast_format_cmp(f->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {
                modem_connect_tones_rx(p->tone_state, f->data.ptr, f->samples);
 
        /* alaw/ulaw frame must be converted to slinear before passing to spandsp */
-       } else if (f->subclass.format.id == AST_FORMAT_ALAW || f->subclass.format.id == AST_FORMAT_ULAW) {
+       } else if (ast_format_cmp(f->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL ||
+                  ast_format_cmp(f->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {
                if (!(slndata = ast_malloc(sizeof(*slndata) * f->samples))) {
                        return -1;
                }
-               decoder = g711_init(NULL, (f->subclass.format.id == AST_FORMAT_ALAW ? G711_ALAW : G711_ULAW));
+               decoder = g711_init(NULL, (ast_format_cmp(f->subclass.format, ast_format_alaw) == AST_FORMAT_CMP_EQUAL ? G711_ALAW : G711_ULAW));
                g711_decode(decoder, slndata, f->data.ptr, f->samples);
-               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"));
+               ast_debug(5, "spandsp transcoding frame from %s to slinear for v21 detection\n", ast_format_get_name(f->subclass.format));
                modem_connect_tones_rx(p->tone_state, slndata, f->samples);
                g711_release(decoder);
 #if SPANDSP_RELEASE_DATE >= 20090220
@@ -687,7 +709,7 @@ static int spandsp_v21_detect(struct ast_fax_session *s, const struct ast_frame
 
        /* frame in other formats cannot be passed to spandsp, it could cause segfault */
        } else {
-               ast_log(LOG_WARNING, "Unknown frame format %u, v.21 detection skipped\n", f->subclass.format.id);
+               ast_log(LOG_WARNING, "Frame format %s not supported, v.21 detection skipped\n", ast_format_get_name(f->subclass.format));
                return -1;
        }
 
@@ -749,6 +771,7 @@ static int spandsp_fax_gw_t30_gen(struct ast_channel *chan, void *data, int len,
        struct ast_frame *f;
        struct ast_frame t30_frame = {
                .frametype = AST_FRAME_VOICE,
+               .subclass.format = ast_format_slin,
                .src = "res_fax_spandsp_g711",
                .samples = samples,
                .flags = AST_FAX_FRFLAG_GATEWAY,
@@ -756,7 +779,6 @@ static int spandsp_fax_gw_t30_gen(struct ast_channel *chan, void *data, int len,
 
        AST_FRAME_SET_BUFFER(&t30_frame, buffer, AST_FRIENDLY_OFFSET, t30_frame.samples * sizeof(int16_t));
 
-       ast_format_set(&t30_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
        if (!(f = ast_frisolate(&t30_frame))) {
                return p->isdone ? -1 : res;
        }
@@ -774,19 +796,22 @@ static int spandsp_fax_gw_t30_gen(struct ast_channel *chan, void *data, int len,
  * \param chan channel
  * \param params generator data
  * \return data to use in generator call*/
-static void *spandsp_fax_gw_gen_alloc(struct ast_channel *chan, void *params) {
+static void *spandsp_fax_gw_gen_alloc(struct ast_channel *chan, void *params)
+{
        ao2_ref(params, +1);
        return params;
 }
 
-static void spandsp_fax_gw_gen_release(struct ast_channel *chan, void *data) {
+static void spandsp_fax_gw_gen_release(struct ast_channel *chan, void *data)
+{
        ao2_ref(data, -1);
 }
 
 /*! \brief activate a spandsp gateway based on the information in the given fax session
  * \param s fax session
  * \return -1 on error 0 on sucess*/
-static int spandsp_fax_gateway_start(struct ast_fax_session *s) {
+static int spandsp_fax_gateway_start(struct ast_fax_session *s)
+{
        struct spandsp_pvt *p = s->tech_pvt;
        struct ast_fax_t38_parameters *t38_param;
        int i;
@@ -811,8 +836,8 @@ static int spandsp_fax_gateway_start(struct ast_fax_session *s) {
 
        p->ist38 = 1;
        p->ast_t38_state = ast_channel_get_t38_state(s->chan);
-       if (!(peer = ast_channel_bridge_peer(s->chan))) {
-               ast_channel_unlock(s->chan);
+       peer = ast_channel_bridge_peer(s->chan);
+       if (!peer) {
                return -1;
        }
 
@@ -834,7 +859,7 @@ static int spandsp_fax_gateway_start(struct ast_fax_session *s) {
        t38_set_fill_bit_removal(p->t38_core_state, t38_param->fill_bit_removal);
        t38_set_mmr_transcoding(p->t38_core_state, t38_param->transcoding_mmr);
        t38_set_jbig_transcoding(p->t38_core_state, t38_param->transcoding_jbig);
-       t38_set_data_rate_management_method(p->t38_core_state, 
+       t38_set_data_rate_management_method(p->t38_core_state,
                        (t38_param->rate_management == AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF)? 1 : 2);
 
        t38_gateway_set_transmit_on_idle(&p->t38_gw_state, TRUE);
@@ -843,7 +868,7 @@ static int spandsp_fax_gateway_start(struct ast_fax_session *s) {
 
        t38_gateway_set_supported_modems(&p->t38_gw_state, spandsp_modems(s->details));
 
-       /* engage udptl nat on other side of T38 line 
+       /* engage udptl nat on other side of T38 line
         * (Asterisk changes media ports thus we send a few packets to reinitialize
         * pinholes in NATs and FWs
         */
@@ -878,7 +903,8 @@ static int spandsp_fax_gateway_process(struct ast_fax_session *s, const struct a
        /* Process a IFP packet */
        if ((f->frametype == AST_FRAME_MODEM) && (f->subclass.integer == AST_MODEM_T38)) {
                return t38_core_rx_ifp_packet(p->t38_core_state, f->data.ptr, f->datalen, f->seqno);
-       } else if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id == AST_FORMAT_SLINEAR)) {
+       } else if ((f->frametype == AST_FRAME_VOICE) &&
+               (ast_format_cmp(f->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)) {
                return t38_gateway_rx(&p->t38_gw_state, f->data.ptr, f->samples);
        }
 
@@ -1237,6 +1263,8 @@ static int load_module(void)
 
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Spandsp G.711 and T.38 FAX Technologies",
-               .load = load_module,
-               .unload = unload_module,
-              );
+       .support_level = AST_MODULE_SUPPORT_EXTENDED,
+       .load = load_module,
+       .unload = unload_module,
+       .enhances = "res_fax",
+);