/*
 * SRTP network protocol
 * Copyright (c) 2012 Martin Storsjo
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg 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 FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "libavutil/opt.h"
#include "avformat.h"
#include "avio_internal.h"
#include "url.h"

#include "internal.h"
#include "rtpdec.h"
#include "srtp.h"

typedef struct SRTPProtoContext {
    const AVClass *class;
    URLContext *rtp_hd;
    const char *out_suite, *out_params;
    const char *in_suite, *in_params;
    struct SRTPContext srtp_out, srtp_in;
    uint8_t encryptbuf[RTP_MAX_PACKET_LENGTH];
} SRTPProtoContext;

#define D AV_OPT_FLAG_DECODING_PARAM
#define E AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
    { "srtp_out_suite", "", offsetof(SRTPProtoContext, out_suite), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
    { "srtp_out_params", "", offsetof(SRTPProtoContext, out_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
    { "srtp_in_suite", "", offsetof(SRTPProtoContext, in_suite), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
    { "srtp_in_params", "", offsetof(SRTPProtoContext, in_params), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
    { NULL }
};

static const AVClass srtp_context_class = {
    .class_name     = "srtp",
    .item_name      = av_default_item_name,
    .option         = options,
    .version        = LIBAVUTIL_VERSION_INT,
};

static int srtp_close(URLContext *h)
{
    SRTPProtoContext *s = h->priv_data;
    ff_srtp_free(&s->srtp_out);
    ff_srtp_free(&s->srtp_in);
    ffurl_close(s->rtp_hd);
    s->rtp_hd = NULL;
    return 0;
}

static int srtp_open(URLContext *h, const char *uri, int flags)
{
    SRTPProtoContext *s = h->priv_data;
    char hostname[256], buf[1024], path[1024];
    int rtp_port, ret;

    if (s->out_suite && s->out_params)
        if ((ret = ff_srtp_set_crypto(&s->srtp_out, s->out_suite, s->out_params)) < 0)
            goto fail;
    if (s->in_suite && s->in_params)
        if ((ret = ff_srtp_set_crypto(&s->srtp_in, s->in_suite, s->in_params)) < 0)
            goto fail;

    av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
                 path, sizeof(path), uri);
    ff_url_join(buf, sizeof(buf), "rtp", NULL, hostname, rtp_port, "%s", path);
    if ((ret = ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback,
                                    NULL, h->protocol_whitelist)) < 0)
        goto fail;

    h->max_packet_size = FFMIN(s->rtp_hd->max_packet_size,
                               sizeof(s->encryptbuf)) - 14;
    h->is_streamed = 1;
    return 0;

fail:
    srtp_close(h);
    return ret;
}

static int srtp_read(URLContext *h, uint8_t *buf, int size)
{
    SRTPProtoContext *s = h->priv_data;
    int ret;
start:
    ret = ffurl_read(s->rtp_hd, buf, size);
    if (ret > 0 && s->srtp_in.aes) {
        if (ff_srtp_decrypt(&s->srtp_in, buf, &ret) < 0)
            goto start;
    }
    return ret;
}

static int srtp_write(URLContext *h, const uint8_t *buf, int size)
{
    SRTPProtoContext *s = h->priv_data;
    if (!s->srtp_out.aes)
        return ffurl_write(s->rtp_hd, buf, size);
    size = ff_srtp_encrypt(&s->srtp_out, buf, size, s->encryptbuf,
                           sizeof(s->encryptbuf));
    if (size < 0)
        return size;
    return ffurl_write(s->rtp_hd, s->encryptbuf, size);
}

static int srtp_get_file_handle(URLContext *h)
{
    SRTPProtoContext *s = h->priv_data;
    return ffurl_get_file_handle(s->rtp_hd);
}

static int srtp_get_multi_file_handle(URLContext *h, int **handles,
                                      int *numhandles)
{
    SRTPProtoContext *s = h->priv_data;
    return ffurl_get_multi_file_handle(s->rtp_hd, handles, numhandles);
}

URLProtocol ff_srtp_protocol = {
    .name                      = "srtp",
    .url_open                  = srtp_open,
    .url_read                  = srtp_read,
    .url_write                 = srtp_write,
    .url_close                 = srtp_close,
    .url_get_file_handle       = srtp_get_file_handle,
    .url_get_multi_file_handle = srtp_get_multi_file_handle,
    .priv_data_size            = sizeof(SRTPProtoContext),
    .priv_data_class           = &srtp_context_class,
    .flags                     = URL_PROTOCOL_FLAG_NETWORK,
};
