/*
 * SpanDSP - a series of DSP components for telephony
 *
 * v42bis.c
 *
 * Written by Steve Underwood <steveu@coppice.org>
 *
 * Copyright (C) 2005, 2011 Steve Underwood
 *
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 2.1,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED. 
   Currently it performs the core compression and decompression functions OK.
   However, a number of the bells and whistles in V.42bis are incomplete. */

/*! \file */

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <assert.h>

#include <osmocom/sgsn/v42bis.h>
#include <osmocom/sgsn/v42bis_private.h>
#include <osmocom/sgsn/debug.h>
#include <osmocom/core/talloc.h>


#define span_log(x,y,msg, ...) DEBUGP(DV42BIS,msg, ##__VA_ARGS__)
#define span_log_init(x,y,z)
#define span_log_set_protocol(x,y)


#define FALSE 0
#define TRUE 1

/* Fixed parameters from the spec. */
/* Character size (bits) */
#define V42BIS_N3                           8
/* Number of characters in the alphabet */
#define V42BIS_N4                           256
/* Index number of first dictionary entry used to store a string */
#define V42BIS_N5                           (V42BIS_N4 + V42BIS_N6)
/* Number of control codewords */
#define V42BIS_N6                           3 
/* V.42bis/9.2 */
#define V42BIS_ESC_STEP                     51

/* Compreeibility monitoring parameters for assessing automated switches between
   transparent and compressed mode */
#define COMPRESSIBILITY_MONITOR             (256*V42BIS_N3)
#define COMPRESSIBILITY_MONITOR_HYSTERESIS  11

/* Control code words in compressed mode */
enum
{
    V42BIS_ETM = 0,         /* Enter transparent mode */
    V42BIS_FLUSH = 1,       /* Flush data */
    V42BIS_STEPUP = 2       /* Step up codeword size */
};

/* Command codes in transparent mode */
enum
{
    V42BIS_ECM = 0,         /* Enter compression mode */
    V42BIS_EID = 1,         /* Escape character in data */
    V42BIS_RESET = 2        /* Force reinitialisation */
};

static __inline__ void push_octet(v42bis_comp_state_t *s, int octet)
{
    s->output_buf[s->output_octet_count++] = (uint8_t) octet;
    if (s->output_octet_count >= s->max_output_len)
    {
        s->handler(s->user_data, s->output_buf, s->output_octet_count);
        s->output_octet_count = 0;
    }
}
/*- End of function --------------------------------------------------------*/

static __inline__ void push_octets(v42bis_comp_state_t *s, const uint8_t buf[], int len)
{
    int i;
    int chunk;

    i = 0;
    while ((s->output_octet_count + len - i) >= s->max_output_len)
    {
        chunk = s->max_output_len - s->output_octet_count;
        memcpy(&s->output_buf[s->output_octet_count], &buf[i], chunk);
        s->handler(s->user_data, s->output_buf, s->max_output_len);
        s->output_octet_count = 0;
        i += chunk;
    }
    chunk = len - i;
    if (chunk > 0)
    {
        memcpy(&s->output_buf[s->output_octet_count], &buf[i], chunk);
        s->output_octet_count += chunk;
    }
}
/*- End of function --------------------------------------------------------*/

static __inline__ void push_compressed_code(v42bis_comp_state_t *s, int code)
{
    s->bit_buffer |= code << s->bit_count;
    s->bit_count += s->v42bis_parm_c2;
    while (s->bit_count >= 8)
    {
        push_octet(s, s->bit_buffer & 0xFF);
        s->bit_buffer >>= 8;
        s->bit_count -= 8;
    }
}
/*- End of function --------------------------------------------------------*/

static __inline__ void push_octet_alignment(v42bis_comp_state_t *s)
{
    if ((s->bit_count & 7))
    {
        s->bit_count += (8 - (s->bit_count & 7));
        while (s->bit_count >= 8)
        {
            push_octet(s, s->bit_buffer & 0xFF);
            s->bit_buffer >>= 8;
            s->bit_count -= 8;
        }
    }
}
/*- End of function --------------------------------------------------------*/

static __inline__ void flush_octets(v42bis_comp_state_t *s)
{
    if (s->output_octet_count > 0)
    {
        s->handler(s->user_data, s->output_buf, s->output_octet_count);
        s->output_octet_count = 0;
    }
}
/*- End of function --------------------------------------------------------*/

static void dictionary_init(v42bis_comp_state_t *s)
{
    int i;

    memset(s->dict, 0, sizeof(s->dict));
    for (i = 0;  i < V42BIS_N4;  i++)
        s->dict[i + V42BIS_N6].node_octet = i;
    s->v42bis_parm_c1 = V42BIS_N5;
    s->v42bis_parm_c2 = V42BIS_N3 + 1;
    s->v42bis_parm_c3 = V42BIS_N4 << 1;
    s->last_matched = 0;
    s->update_at = 0;
    s->last_added = 0;
    s->bit_buffer = 0;
    s->bit_count = 0;
    s->flushed_length = 0;
    s->string_length = 0;
    s->escape_code = 0;
    s->transparent = TRUE;
    s->escaped = FALSE;
    s->compression_performance = COMPRESSIBILITY_MONITOR;
}
/*- End of function --------------------------------------------------------*/

static uint16_t match_octet(v42bis_comp_state_t *s, uint16_t at, uint8_t octet)
{
    uint16_t e;

    if (at == 0)
        return octet + V42BIS_N6;
    e = s->dict[at].child;
    while (e)
    {
        if (s->dict[e].node_octet == octet)
            return e;
        e = s->dict[e].next;
    }
    return 0;
}
/*- End of function --------------------------------------------------------*/

static uint16_t add_octet_to_dictionary(v42bis_comp_state_t *s, uint16_t at, uint8_t octet)
{
    uint16_t newx;
    uint16_t next;
    uint16_t e;

    newx = s->v42bis_parm_c1;
    s->dict[newx].node_octet = octet;
    s->dict[newx].parent = at;
    s->dict[newx].child = 0;
    s->dict[newx].next = s->dict[at].child;
    s->dict[at].child = newx;
    next = newx;
    /* 6.5 Recovering a dictionary entry to use next */
    do
    {
        /* 6.5(a) and (b) */
        if (++next == s->v42bis_parm_n2)
            next = V42BIS_N5;
    }
    while (s->dict[next].child);
    /* 6.5(c) We need to reuse a leaf node */
    if (s->dict[next].parent)
    {
        /* 6.5(d) Detach the leaf node from its parent, and re-use it */
        e = s->dict[next].parent;
        if (s->dict[e].child == next)
        {
            s->dict[e].child = s->dict[next].next;
        }
        else
        {
            e = s->dict[e].child;
            while (s->dict[e].next != next)
                e = s->dict[e].next;
            s->dict[e].next = s->dict[next].next;
        }
    }
    s->v42bis_parm_c1 = next;
    return newx;
}
/*- End of function --------------------------------------------------------*/

static void send_string(v42bis_comp_state_t *s)
{
    push_octets(s, s->string, s->string_length);
    s->string_length = 0;
    s->flushed_length = 0;
}
/*- End of function --------------------------------------------------------*/

static void expand_codeword_to_string(v42bis_comp_state_t *s, uint16_t code)
{
    int i;
    uint16_t p;

    /* Work out the length */
    for (i = 0, p = code;  p;  i++)
        p = s->dict[p].parent;
    s->string_length += i;
    /* Now expand the known length of string */
    i = s->string_length - 1;
    for (p = code;  p;  )
    {
        s->string[i--] = s->dict[p].node_octet;
        p = s->dict[p].parent;
    }
}
/*- End of function --------------------------------------------------------*/

static void send_encoded_data(v42bis_comp_state_t *s, uint16_t code)
{
    int i;

    /* Update compressibility metric */
    /* Integrate at the compressed bit rate, and leak at the pre-compression bit rate */
    s->compression_performance += (s->v42bis_parm_c2 - s->compression_performance*s->string_length*V42BIS_N3/COMPRESSIBILITY_MONITOR);
    if (s->transparent)
    {
        for (i = 0;  i < s->string_length;  i++)
        {
            push_octet(s, s->string[i]);
            if (s->string[i] == s->escape_code)
            {
                push_octet(s, V42BIS_EID);
                s->escape_code += V42BIS_ESC_STEP;
            }
        }
    }
    else
    {
        /* Allow for any escape octets in the string */
        for (i = 0;  i < s->string_length;  i++)
        {
            if (s->string[i] == s->escape_code)
                s->escape_code += V42BIS_ESC_STEP;
        }
        /* 7.4 Encoding - we now have the longest matchable string, and will need to output the code for it. */
        while (code >= s->v42bis_parm_c3)
        {
            /* We need to increase the codeword size */
            /* 7.4(a) */
            push_compressed_code(s, V42BIS_STEPUP);
            /* 7.4(b) */
            s->v42bis_parm_c2++;
            /* 7.4(c) */
            s->v42bis_parm_c3 <<= 1;
            /* 7.4(d) this might need to be repeated, so we loop */
        }
        /* 7.5 Transfer - output the last state of the string */
        push_compressed_code(s, code);
    }
    s->string_length = 0;
    s->flushed_length = 0;
}
/*- End of function --------------------------------------------------------*/

static void go_compressed(v42bis_state_t *ss)
{
    v42bis_comp_state_t *s;

    s = &ss->compress;
    if (!s->transparent)
        return;
    span_log(&ss->logging, SPAN_LOG_FLOW, "Changing to compressed mode\n");
    /* Switch out of transparent now, between codes. We need to send the octet which did not
       match, just before switching. */
    if (s->last_matched)
    {
        s->update_at = s->last_matched;
        send_encoded_data(s, s->last_matched);
        s->last_matched = 0;
    }
    push_octet(s, s->escape_code);
    push_octet(s, V42BIS_ECM);
    s->bit_buffer = 0;
    s->transparent = FALSE;
}
/*- End of function --------------------------------------------------------*/

static void go_transparent(v42bis_state_t *ss)
{
    v42bis_comp_state_t *s;

    s = &ss->compress;
    if (s->transparent)
        return;
    span_log(&ss->logging, SPAN_LOG_FLOW, "Changing to transparent mode\n");
    /* Switch into transparent now, between codes, and the unmatched octet should
       go out in transparent mode, just below */
    if (s->last_matched)
    {
        s->update_at = s->last_matched;
        send_encoded_data(s, s->last_matched);
        s->last_matched = 0;
    }
    s->last_added = 0;
    push_compressed_code(s, V42BIS_ETM);
    push_octet_alignment(s);
    s->transparent = TRUE;
}
/*- End of function --------------------------------------------------------*/

static void monitor_for_mode_change(v42bis_state_t *ss)
{
    v42bis_comp_state_t *s;

    s = &ss->compress;
    switch (s->compression_mode)
    {
    case V42BIS_COMPRESSION_MODE_DYNAMIC:
        /* 7.8 Data compressibility test */
        if (s->transparent)
        {
            if (s->compression_performance < COMPRESSIBILITY_MONITOR - COMPRESSIBILITY_MONITOR_HYSTERESIS)
            {
                /* 7.8.1 Transition to compressed mode */
                go_compressed(ss);
            }
        }
        else
        {
            if (s->compression_performance > COMPRESSIBILITY_MONITOR)
            {
                /* 7.8.2 Transition to transparent mode */
                go_transparent(ss);
            }
        }
        /* 7.8.3 Reset function - TODO */
        break;
    case V42BIS_COMPRESSION_MODE_ALWAYS:
        if (s->transparent)
            go_compressed(ss);
        break;
    case V42BIS_COMPRESSION_MODE_NEVER:
        if (!s->transparent)
            go_transparent(ss);
        break;
    }
}
/*- End of function --------------------------------------------------------*/

static int v42bis_comp_init(v42bis_comp_state_t *s,
                            int p1,
                            int p2,
                            put_msg_func_t handler,
                            void *user_data,
                            int max_output_len)
{
    memset(s, 0, sizeof(*s));
    s->v42bis_parm_n2 = p1;
    s->v42bis_parm_n7 = p2;
    s->handler = handler;
    s->user_data = user_data;
    s->max_output_len = (max_output_len < V42BIS_MAX_OUTPUT_LENGTH)  ?  max_output_len  :  V42BIS_MAX_OUTPUT_LENGTH;
    s->output_octet_count = 0;
    dictionary_init(s);
    return 0;
}
/*- End of function --------------------------------------------------------*/

static int comp_exit(v42bis_comp_state_t *s)
{
    s->v42bis_parm_n2 = 0;
    return 0;
}
/*- End of function --------------------------------------------------------*/

SPAN_DECLARE(int) v42bis_compress(v42bis_state_t *ss, const uint8_t buf[], int len)
{
    v42bis_comp_state_t *s;
    int i;
    uint16_t code;

    s = &ss->compress;
    if (!s->v42bis_parm_p0)
    {
        /* Compression is off - just push the incoming data out */
        push_octets(s, buf, len);
        return 0;
    }
    for (i = 0;  i < len;  )
    {
        /* 6.4 Add the string to the dictionary */
        if (s->update_at)
        {
            if (match_octet(s, s->update_at, buf[i]) == 0)
                s->last_added = add_octet_to_dictionary(s, s->update_at, buf[i]);
            s->update_at = 0;
        }
        /* Match string */
        while (i < len)
        {
            code = match_octet(s, s->last_matched, buf[i]);
            if (code == 0)
            {
                s->update_at = s->last_matched;
                send_encoded_data(s, s->last_matched);
                s->last_matched = 0;
                break;
            }
            if (code == s->last_added)
            {
                s->last_added = 0;
                send_encoded_data(s, s->last_matched);
                s->last_matched = 0;
                break;
            }
            s->last_matched = code;
            /* 6.3(b) If the string matches a dictionary entry, and the entry is not that entry
                      created by the last invocation of the string matching procedure, then the
                      next character shall be read and appended to the string and this step
                      repeated. */
            s->string[s->string_length++] = buf[i++];
            /* 6.4(a) The string must not exceed N7 in length */
            if (s->string_length + s->flushed_length == s->v42bis_parm_n7)
            {
                send_encoded_data(s, s->last_matched);
                s->last_matched = 0;
                break;
            }
        }
        monitor_for_mode_change(ss);
    }
    return 0;
}
/*- End of function --------------------------------------------------------*/

SPAN_DECLARE(int) v42bis_compress_flush(v42bis_state_t *ss)
{
    v42bis_comp_state_t *s;
    int len;
    
    s = &ss->compress;
    if (s->update_at)
        return 0;
    if (s->last_matched)
    {
        len = s->string_length;
        send_encoded_data(s, s->last_matched);
        s->flushed_length += len;
    }
    if (!s->transparent)
    {
        s->update_at = s->last_matched;
        s->last_matched = 0;
        s->flushed_length = 0;
        push_compressed_code(s, V42BIS_FLUSH);
        push_octet_alignment(s);
    }
    flush_octets(s);
    return 0;
}
/*- End of function --------------------------------------------------------*/

SPAN_DECLARE(int) v42bis_decompress(v42bis_state_t *ss, const uint8_t buf[], int len)
{
    v42bis_comp_state_t *s;
    int i;
    int j;
    int yyy;
    uint16_t code;
    uint16_t p;
    uint8_t ch;
    uint8_t in;

    s = &ss->decompress;
    if (!s->v42bis_parm_p0)
    {
        /* Compression is off - just push the incoming data out */
        push_octets(s, buf, len);
        return 0;
    }
    for (i = 0;  i < len;  )
    {
        if (s->transparent)
        {
            in = buf[i];
            if (s->escaped)
            {
                /* Command */
                s->escaped = FALSE;
                switch (in)
                {
                case V42BIS_ECM:
                    /* Enter compressed mode */
                    span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_ECM\n");
                    send_string(s);
                    s->transparent = FALSE;
                    s->update_at = s->last_matched;
                    s->last_matched = 0;
                    i++;
                    continue;
                case V42BIS_EID:
                    /* Escape symbol */
                    span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_EID\n");
                    in = s->escape_code;
                    s->escape_code += V42BIS_ESC_STEP;
                    break;
                case V42BIS_RESET:
                    /* Reset dictionary */
                    span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_RESET\n");
                    /* TODO: */
                    send_string(s);
                    dictionary_init(s);
                    i++;
                    continue;
                default:
                    span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_???? - %" PRIu32 "\n", in);
                    return -1;
                }
            }
            else if (in == s->escape_code)
            {
                s->escaped = TRUE;
                i++;
                continue;
            }

            yyy = TRUE;
            for (j = 0;  j < 2  &&  yyy;  j++)
            {
                if (s->update_at)
                {
                    if (match_octet(s, s->update_at, in) == 0)
                        s->last_added = add_octet_to_dictionary(s, s->update_at, in);
                    s->update_at = 0;
                }

                code = match_octet(s, s->last_matched, in);
                if (code == 0)
                {
                    s->update_at = s->last_matched;
                    send_string(s);
                    s->last_matched = 0;
                }
                else if (code == s->last_added)
                {
                    s->last_added = 0;
                    send_string(s);
                    s->last_matched = 0;
                }
                else
                {
                    s->last_matched = code;
                    s->string[s->string_length++] = in;
                    if (s->string_length + s->flushed_length == s->v42bis_parm_n7)
                    {
                        send_string(s);
                        s->last_matched = 0;
                    }
                    i++;
                    yyy = FALSE;
                }
            }
        }
        else
        {
            /* Get code from input */
            while (s->bit_count < s->v42bis_parm_c2  &&  i < len)
            {
                s->bit_buffer |= buf[i++] << s->bit_count;
                s->bit_count += 8;
            }
            if (s->bit_count < s->v42bis_parm_c2)
                continue;
            code = s->bit_buffer & ((1 << s->v42bis_parm_c2) - 1);
            s->bit_buffer >>= s->v42bis_parm_c2;
            s->bit_count -= s->v42bis_parm_c2;

            if (code < V42BIS_N6)
            {
                /* We have a control code. */
                switch (code)
                {
                case V42BIS_ETM:
                    /* Enter transparent mode */
                    span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_ETM\n");
                    s->bit_count = 0;
                    s->transparent = TRUE;
                    s->last_matched = 0;
                    s->last_added = 0;
                    break;
                case V42BIS_FLUSH:
                    /* Flush signal */
                    span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_FLUSH\n");
                    s->bit_count = 0;
                    break;
                case V42BIS_STEPUP:
                    /* Increase code word size */
                    span_log(&ss->logging, SPAN_LOG_FLOW, "Hit V42BIS_STEPUP\n");
                    s->v42bis_parm_c2++;
                    s->v42bis_parm_c3 <<= 1;
                    if (s->v42bis_parm_c2 > (s->v42bis_parm_n2 >> 3))
                        return -1;
                    break;
                }
                continue;
            }
            /* Regular codeword */
            if (code == s->v42bis_parm_c1)
                return -1;
            expand_codeword_to_string(s, code);
            if (s->update_at)
            {
                ch = s->string[0];
                if ((p = match_octet(s, s->update_at, ch)) == 0)
                {
                    s->last_added = add_octet_to_dictionary(s, s->update_at, ch);
                    if (code == s->v42bis_parm_c1)
                        return -1;
                }
                else if (p == s->last_added)
                {
                    s->last_added = 0;
                }
            }
            s->update_at = ((s->string_length + s->flushed_length) == s->v42bis_parm_n7)  ?  0  :  code;
            /* Allow for any escapes which may be in this string */
            for (j = 0;  j < s->string_length;  j++)
            {
                if (s->string[j] == s->escape_code)
                    s->escape_code += V42BIS_ESC_STEP;
            }
            send_string(s);
        }
    }
    return 0;
}
/*- End of function --------------------------------------------------------*/

SPAN_DECLARE(int) v42bis_decompress_flush(v42bis_state_t *ss)
{
    v42bis_comp_state_t *s;
    int len;
    
    s = &ss->decompress;
    len = s->string_length;
    send_string(s);
    s->flushed_length += len;
    flush_octets(s);
    return 0;
}
/*- End of function --------------------------------------------------------*/

SPAN_DECLARE(void) v42bis_compression_control(v42bis_state_t *s, int mode)
{
    s->compress.compression_mode = mode;
}
/*- End of function --------------------------------------------------------*/

SPAN_DECLARE(v42bis_state_t *) v42bis_init(const void *ctx,
                                           v42bis_state_t *s,
                                           int negotiated_p0,
                                           int negotiated_p1,
                                           int negotiated_p2,
                                           put_msg_func_t encode_handler,
                                           void *encode_user_data,
                                           int max_encode_len,
                                           put_msg_func_t decode_handler,
                                           void *decode_user_data,
                                           int max_decode_len)
{
    int ret;

    if (negotiated_p1 < V42BIS_MIN_DICTIONARY_SIZE  ||  negotiated_p1 > 65535)
        return NULL;
    if (negotiated_p2 < V42BIS_MIN_STRING_SIZE  ||  negotiated_p2 > V42BIS_MAX_STRING_SIZE)
        return NULL;
    if (s == NULL)
    {
        if ((s = (v42bis_state_t *) talloc_zero_size(ctx,sizeof(*s))) == NULL)
            return NULL;
    }
    memset(s, 0, sizeof(*s));
    span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
    span_log_set_protocol(&s->logging, "V.42bis");

    if ((ret = v42bis_comp_init(&s->compress, negotiated_p1, negotiated_p2, encode_handler, encode_user_data, max_encode_len)))
        return NULL;
    if ((ret = v42bis_comp_init(&s->decompress, negotiated_p1, negotiated_p2, decode_handler, decode_user_data, max_decode_len)))
    {
        comp_exit(&s->compress);
        return NULL;
    }
    s->compress.v42bis_parm_p0 = negotiated_p0 & 2;
    s->decompress.v42bis_parm_p0 = negotiated_p0 & 1;

    return s;
}
/*- End of function --------------------------------------------------------*/

SPAN_DECLARE(int) v42bis_release(v42bis_state_t *s)
{
    return 0;
}
/*- End of function --------------------------------------------------------*/

SPAN_DECLARE(int) v42bis_free(v42bis_state_t *s)
{
    comp_exit(&s->compress);
    comp_exit(&s->decompress);
    talloc_free(s);
    return 0;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
