/*
 * 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, h->protocol_blacklist, h)) < 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);
}

const 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,
};
