/* GStreamer - Remote Audio Access Protocol (RAOP) as used in Apple iTunes to stream music to the Airport Express (ApEx) -
 *
 * RAOP is based on the Real Time Streaming Protocol (RTSP) but with an extra challenge-response RSA based authentication step.
 * This interface accepts RAW PCM data and set it as AES encrypted ALAC while performing emission.
 *
 * Copyright (C) 2008 Jérémie Bernard [GRemi] <gremimail@gmail.com>
 *
 * gstapexraop.c
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>

#include "gstapexraop.h"

/* private constants */
#define GST_APEX_RAOP_VOLUME_MIN 	-144
#define GST_APEX_RAOP_VOLUME_MAX  	 0

#define GST_APEX_RAOP_HDR_DEFAULT_LENGTH 1024
#define GST_APEX_RAOP_SDP_DEFAULT_LENGTH 2048

const static gchar GST_APEX_RAOP_RSA_PUBLIC_MOD[] =
    "59dE8qLieItsH1WgjrcFRKj6eUWqi+bGLOX1HL3U3GhC/j0Qg90u3sG/1CUtwC"
    "5vOYvfDmFI6oSFXi5ELabWJmT2dKHzBJKa3k9ok+8t9ucRqMd6DZHJ2YCCLlDR"
    "KSKv6kDqnw4UwPdpOMXziC/AMj3Z/lUVX1G7WSHCAWKf1zNS1eLvqr+boEjXuB"
    "OitnZ/bDzPHrTOZz0Dew0uowxf/+sG+NCK3eQJVxqcaJ/vEHKIVd2M+5qL71yJ"
    "Q+87X6oV3eaYvt3zWZYD6z5vYTcrtij2VZ9Zmni/UAaHqn9JdsBWLUEpVviYnh"
    "imNVvYFZeCXg/IdTQ+x4IRdiXNv5hEew==";

const static gchar GST_APEX_RAOP_RSA_PUBLIC_EXP[] = "AQAB";

const static gchar GST_APEX_RAOP_USER_AGENT[] =
    "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)";

const static guchar GST_APEX_RAOP_FRAME_HEADER[] = {    // Used by gen. 1
  0x24, 0x00, 0x00, 0x00,
  0xF0, 0xFF, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00
};

const static int GST_APEX_RAOP_FRAME_HEADER_SIZE = 16;  // Used by gen. 1
const static int GST_APEX_RTP_FRAME_HEADER_SIZE = 12;   // Used by gen. 2

const static int GST_APEX_RAOP_ALAC_HEADER_SIZE = 3;

/* string extra utility */
static gint
g_strdel (gchar * str, gchar rc)
{
  int i = 0, j = 0, len, num = 0;
  len = strlen (str);
  while (i < len) {
    if (str[i] == rc) {
      for (j = i; j < len; j++)
        str[j] = str[j + 1];
      len--;
      num++;
    } else {
      i++;
    }
  }
  return num;
}

/* socket utilities */
static int
gst_apexraop_send (int desc, void *data, size_t len)
{
  int total = 0, bytesleft = len, n = 0;

  while (total < len) {
    n = send (desc, ((const char *) data) + total, bytesleft, 0);
    if (n == -1)
      break;
    total += n;
    bytesleft -= n;
  }

  return n == -1 ? -1 : total;
}

static int
gst_apexraop_recv (int desc, void *data, size_t len)
{
  memset (data, 0, len);
  return recv (desc, data, len, 0);
}

/* public opaque handle resolution */
typedef struct
{
  guchar aes_ky[AES_BLOCK_SIZE];        /* AES random key */
  guchar aes_iv[AES_BLOCK_SIZE];        /* AES random initial vector */

  guchar url_abspath[16];       /* header url random absolute path addon, ANNOUNCE id */
  gint cseq;                    /* header rtsp inc cseq */
  guchar cid[24];               /* header client instance id */
  gchar *session;               /* header raop negotiated session id, once SETUP performed */
  gchar *ua;                    /* header user agent */

  GstApExJackType jack_type;    /* APEX connected jack type, once ANNOUNCE performed */
  GstApExJackStatus jack_status;        /* APEX connected jack status, once ANNOUNCE performed */

  GstApExGeneration generation; /* Different devices accept different audio streams */
  GstApExTransportProtocol transport_protocol;  /* For media stream, not RAOP/RTSP */

  gchar *host;                  /* APEX target ip */
  guint ctrl_port;              /* APEX target control port */
  guint data_port;              /* APEX negotiated data port, once SETUP performed */

  int ctrl_sd;                  /* control socket */
  struct sockaddr_in ctrl_sd_in;

  int data_sd;                  /* data socket */
  struct sockaddr_in data_sd_in;

  short rtp_seq_num;            /* RTP sequence number, used by gen. 2 */
  int rtp_timestamp;            /* RTP timestamp,       used by gen. 2 */
}
_GstApExRAOP;

/* raop apex struct allocation */
GstApExRAOP *
gst_apexraop_new (const gchar * host,
    const guint16 port,
    const GstApExGeneration generation,
    const GstApExTransportProtocol transport_protocol)
{
  _GstApExRAOP *apexraop;

  apexraop = (_GstApExRAOP *) g_malloc0 (sizeof (_GstApExRAOP));

  apexraop->host = g_strdup (host);
  apexraop->ctrl_port = port;
  apexraop->ua = g_strdup (GST_APEX_RAOP_USER_AGENT);
  apexraop->jack_type = GST_APEX_JACK_TYPE_UNDEFINED;
  apexraop->jack_status = GST_APEX_JACK_STATUS_DISCONNECTED;
  apexraop->generation = generation;
  apexraop->transport_protocol = transport_protocol;
  apexraop->rtp_seq_num = 0;
  apexraop->rtp_timestamp = 0;

  return (GstApExRAOP *) apexraop;
}

/* raop apex struct freeing */
void
gst_apexraop_free (GstApExRAOP * con)
{
  _GstApExRAOP *conn;
  conn = (_GstApExRAOP *) con;

  g_free (conn->host);
  g_free (conn->session);
  g_free (conn->ua);
  g_free (conn);
}

/* host affectation */
void
gst_apexraop_set_host (GstApExRAOP * con, const gchar * host)
{
  _GstApExRAOP *conn;
  conn = (_GstApExRAOP *) con;

  g_free (conn->host);
  conn->host = g_strdup (host);
}

/* host reader */
gchar *
gst_apexraop_get_host (GstApExRAOP * con)
{
  _GstApExRAOP *conn;
  conn = (_GstApExRAOP *) con;

  return g_strdup (conn->host);
}

/* control port affectation */
void
gst_apexraop_set_port (GstApExRAOP * con, const guint16 port)
{
  _GstApExRAOP *conn;
  conn = (_GstApExRAOP *) con;

  conn->ctrl_port = port;
}

/* control port reader */
guint16
gst_apexraop_get_port (GstApExRAOP * con)
{
  _GstApExRAOP *conn;
  conn = (_GstApExRAOP *) con;

  return conn->ctrl_port;
}

/* user agent affectation */
void
gst_apexraop_set_useragent (GstApExRAOP * con, const gchar * useragent)
{
  _GstApExRAOP *conn;
  conn = (_GstApExRAOP *) con;

  g_free (conn->ua);
  conn->ua = g_strdup (useragent);
}

/* user agent reader */
gchar *
gst_apexraop_get_useragent (GstApExRAOP * con)
{
  _GstApExRAOP *conn;
  conn = (_GstApExRAOP *) con;

  return g_strdup (conn->ua);
}

/* raop apex connection sequence */
GstRTSPStatusCode
gst_apexraop_connect (GstApExRAOP * con)
{
  gchar *ac, *ky, *iv, *s, inaddr[INET_ADDRSTRLEN],
      creq[GST_APEX_RAOP_SDP_DEFAULT_LENGTH],
      hreq[GST_APEX_RAOP_HDR_DEFAULT_LENGTH], *req;
  RSA *rsa;
  guchar *mod, *exp, rsakey[512];
  union gst_randbytes
  {
    struct asvals
    {
      guint32 url_key;
      guint64 conn_id;
      guchar challenge[16];
    } v;
    guchar buf[4 + 8 + 16];
  } randbuf;
  gsize size;
  struct sockaddr_in ioaddr;
  socklen_t iolen;
  GstRTSPStatusCode res;
  _GstApExRAOP *conn;

  conn = (_GstApExRAOP *) con;

  if ((conn->ctrl_sd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    return GST_RTSP_STS_DESTINATION_UNREACHABLE;

  conn->ctrl_sd_in.sin_family = AF_INET;
  conn->ctrl_sd_in.sin_port = htons (conn->ctrl_port);

  if (!inet_aton (conn->host, &conn->ctrl_sd_in.sin_addr)) {
    struct hostent *hp = (struct hostent *) gethostbyname (conn->host);
    if (hp == NULL)
      return GST_RTSP_STS_DESTINATION_UNREACHABLE;
    memcpy (&conn->ctrl_sd_in.sin_addr, hp->h_addr, hp->h_length);
  }

  if (connect (conn->ctrl_sd, (struct sockaddr *) &conn->ctrl_sd_in,
          sizeof (conn->ctrl_sd_in)) < 0)
    return GST_RTSP_STS_DESTINATION_UNREACHABLE;

  RAND_bytes (randbuf.buf, sizeof (randbuf));
  sprintf ((gchar *) conn->url_abspath, "%u", randbuf.v.url_key);
  sprintf ((char *) conn->cid, "%16" G_GINT64_MODIFIER "x", randbuf.v.conn_id);

  RAND_bytes (conn->aes_ky, AES_BLOCK_SIZE);
  RAND_bytes (conn->aes_iv, AES_BLOCK_SIZE);

  rsa = RSA_new ();
  mod = g_base64_decode (GST_APEX_RAOP_RSA_PUBLIC_MOD, &size);
  rsa->n = BN_bin2bn (mod, size, NULL);
  exp = g_base64_decode (GST_APEX_RAOP_RSA_PUBLIC_EXP, &size);
  rsa->e = BN_bin2bn (exp, size, NULL);
  size =
      RSA_public_encrypt (AES_BLOCK_SIZE, conn->aes_ky, rsakey, rsa,
      RSA_PKCS1_OAEP_PADDING);

  ky = g_base64_encode (rsakey, size);
  iv = g_base64_encode (conn->aes_iv, AES_BLOCK_SIZE);
  g_strdel (ky, '=');
  g_strdel (iv, '=');

  iolen = sizeof (struct sockaddr);
  getsockname (conn->ctrl_sd, (struct sockaddr *) &ioaddr, &iolen);
  inet_ntop (AF_INET, &(ioaddr.sin_addr), inaddr, INET_ADDRSTRLEN);

  ac = g_base64_encode (randbuf.v.challenge, 16);
  g_strdel (ac, '=');

  sprintf (creq,
      "v=0\r\n"
      "o=iTunes %s 0 IN IP4 %s\r\n"
      "s=iTunes\r\n"
      "c=IN IP4 %s\r\n"
      "t=0 0\r\n"
      "m=audio 0 RTP/AVP 96\r\n"
      "a=rtpmap:96 AppleLossless\r\n"
      "a=fmtp:96 %d 0 %d 40 10 14 %d 255 0 0 %d\r\n"
      "a=rsaaeskey:%s\r\n"
      "a=aesiv:%s\r\n",
      conn->url_abspath,
      inaddr,
      conn->host,
      conn->generation == GST_APEX_GENERATION_ONE
      ? GST_APEX_RAOP_V1_SAMPLES_PER_FRAME
      : GST_APEX_RAOP_V2_SAMPLES_PER_FRAME,
      GST_APEX_RAOP_BYTES_PER_CHANNEL * 8,
      GST_APEX_RAOP_CHANNELS, GST_APEX_RAOP_BITRATE, ky, iv);

  sprintf (hreq,
      "ANNOUNCE rtsp://%s/%s RTSP/1.0\r\n"
      "CSeq: %d\r\n"
      "Client-Instance: %s\r\n"
      "User-Agent: %s\r\n"
      "Content-Type: application/sdp\r\n"
      "Content-Length: %u\r\n"
      "Apple-Challenge: %s\r\n",
      conn->host,
      conn->url_abspath, ++conn->cseq, conn->cid, conn->ua,
      (guint) strlen (creq), ac);

  RSA_free (rsa);
  g_free (ky);
  g_free (iv);
  g_free (ac);
  g_free (mod);
  g_free (exp);

  req = g_strconcat (hreq, "\r\n", creq, NULL);

  if (gst_apexraop_send (conn->ctrl_sd, req, strlen (req)) <= 0) {
    g_free (req);
    return GST_RTSP_STS_GONE;
  }

  g_free (req);

  if (gst_apexraop_recv (conn->ctrl_sd, hreq,
          GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
    return GST_RTSP_STS_GONE;

  {
    int tmp;
    sscanf (hreq, "%*s %d", &tmp);
    res = (GstRTSPStatusCode) tmp;
  }

  if (res != GST_RTSP_STS_OK)
    return res;

  s = g_strrstr (hreq, "Audio-Jack-Status");

  if (s != NULL) {
    gchar status[128];
    sscanf (s, "%*s %s", status);

    if (strcmp (status, "connected;") == 0)
      conn->jack_status = GST_APEX_JACK_STATUS_CONNECTED;
    else if (strcmp (status, "disconnected;") == 0)
      conn->jack_status = GST_APEX_JACK_STATUS_DISCONNECTED;
    else
      conn->jack_status = GST_APEX_JACK_STATUS_UNDEFINED;

    s = g_strrstr (s, "type=");

    if (s != NULL) {
      strtok (s, "=");
      s = strtok (NULL, "\n");

      if (strcmp (s, "analog"))
        conn->jack_type = GST_APEX_JACK_TYPE_ANALOG;
      else if (strcmp (s, "digital"))
        conn->jack_type = GST_APEX_JACK_TYPE_DIGITAL;
      else
        conn->jack_type = GST_APEX_JACK_TYPE_UNDEFINED;
    }
  }

  sprintf (hreq,
      "SETUP rtsp://%s/%s RTSP/1.0\r\n"
      "CSeq: %d\r\n"
      "Client-Instance: %s\r\n"
      "User-Agent: %s\r\n"
      "Transport: RTP/AVP/TCP;unicast;interleaved=0-1;mode=record\r\n"
      "\r\n", conn->host, conn->url_abspath, ++conn->cseq, conn->cid, conn->ua);

  if (gst_apexraop_send (conn->ctrl_sd, hreq, strlen (hreq)) <= 0)
    return GST_RTSP_STS_GONE;

  if (gst_apexraop_recv (conn->ctrl_sd, hreq,
          GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
    return GST_RTSP_STS_GONE;

  {
    int tmp;
    sscanf (hreq, "%*s %d", &tmp);
    res = (GstRTSPStatusCode) tmp;
  }

  if (res != GST_RTSP_STS_OK)
    return res;

  s = g_strrstr (hreq, "Session");

  if (s != NULL) {
    gchar session[128];
    sscanf (s, "%*s %s", session);
    conn->session = g_strdup (session);
  } else
    return GST_RTSP_STS_PRECONDITION_FAILED;

  s = g_strrstr (hreq, "server_port");
  if (s != NULL) {
    sscanf (s, "server_port=%d", &conn->data_port);
  } else
    return GST_RTSP_STS_PRECONDITION_FAILED;

  sprintf (hreq,
      "RECORD rtsp://%s/%s RTSP/1.0\r\n"
      "CSeq: %d\r\n"
      "Client-Instance: %s\r\n"
      "User-Agent: %s\r\n"
      "Session: %s\r\n"
      "Range: npt=0-\r\n"
      "RTP-Info: seq=0;rtptime=0\r\n"
      "\r\n",
      conn->host,
      conn->url_abspath, ++conn->cseq, conn->cid, conn->ua, conn->session);

  if (gst_apexraop_send (conn->ctrl_sd, hreq, strlen (hreq)) <= 0)
    return GST_RTSP_STS_GONE;

  if (gst_apexraop_recv (conn->ctrl_sd, hreq,
          GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
    return GST_RTSP_STS_GONE;

  {
    int tmp;
    sscanf (hreq, "%*s %d", &tmp);
    res = (GstRTSPStatusCode) tmp;
  }

  if (res != GST_RTSP_STS_OK)
    return res;

  if (conn->transport_protocol == GST_APEX_TCP) {
    if ((conn->data_sd = socket (AF_INET, SOCK_STREAM, 0)) < 0)
      return GST_RTSP_STS_DESTINATION_UNREACHABLE;
  } else if (conn->transport_protocol == GST_APEX_UDP) {
    if ((conn->data_sd = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
      return GST_RTSP_STS_DESTINATION_UNREACHABLE;
  } else
    return GST_RTSP_STS_METHOD_NOT_ALLOWED;

  conn->data_sd_in.sin_family = AF_INET;
  conn->data_sd_in.sin_port = htons (conn->data_port);

  memcpy (&conn->data_sd_in.sin_addr, &conn->ctrl_sd_in.sin_addr,
      sizeof (conn->ctrl_sd_in.sin_addr));

  if (connect (conn->data_sd, (struct sockaddr *) &conn->data_sd_in,
          sizeof (conn->data_sd_in)) < 0)
    return GST_RTSP_STS_DESTINATION_UNREACHABLE;

  return res;
}

/* raop apex jack type access */
GstApExJackType
gst_apexraop_get_jacktype (GstApExRAOP * con)
{
  _GstApExRAOP *conn;

  conn = (_GstApExRAOP *) con;

  if (!conn)
    return GST_APEX_JACK_TYPE_UNDEFINED;

  return conn->jack_type;
}

/* raop apex jack status access */
GstApExJackStatus
gst_apexraop_get_jackstatus (GstApExRAOP * con)
{
  _GstApExRAOP *conn;

  conn = (_GstApExRAOP *) con;

  if (!conn)
    return GST_APEX_JACK_STATUS_UNDEFINED;

  return conn->jack_status;
}

/* raop apex generation access */
GstApExGeneration
gst_apexraop_get_generation (GstApExRAOP * con)
{
  _GstApExRAOP *conn;

  conn = (_GstApExRAOP *) con;

  if (!conn)
    return GST_APEX_GENERATION_ONE;

  return conn->generation;
}

/* raop apex transport protocol access */
GstApExTransportProtocol
gst_apexraop_get_transport_protocol (GstApExRAOP * con)
{
  _GstApExRAOP *conn;

  conn = (_GstApExRAOP *) con;

  if (!conn)
    return GST_APEX_TCP;

  return conn->transport_protocol;
}

/* raop apex sockets close */
void
gst_apexraop_close (GstApExRAOP * con)
{
  gchar hreq[GST_APEX_RAOP_HDR_DEFAULT_LENGTH];
  _GstApExRAOP *conn;

  conn = (_GstApExRAOP *) con;

  sprintf (hreq,
      "TEARDOWN rtsp://%s/%s RTSP/1.0\r\n"
      "CSeq: %d\r\n"
      "Client-Instance: %s\r\n"
      "User-Agent: %s\r\n"
      "Session: %s\r\n"
      "\r\n",
      conn->host,
      conn->url_abspath, ++conn->cseq, conn->cid, conn->ua, conn->session);

  gst_apexraop_send (conn->ctrl_sd, hreq, strlen (hreq));
  gst_apexraop_recv (conn->ctrl_sd, hreq, GST_APEX_RAOP_HDR_DEFAULT_LENGTH);

  if (conn->ctrl_sd != 0)
    close (conn->ctrl_sd);
  if (conn->data_sd != 0)
    close (conn->data_sd);
}

/* raop apex volume set */
GstRTSPStatusCode
gst_apexraop_set_volume (GstApExRAOP * con, const guint volume)
{
  gint v;
  gchar creq[GST_APEX_RAOP_SDP_DEFAULT_LENGTH],
      hreq[GST_APEX_RAOP_HDR_DEFAULT_LENGTH], *req, vol[128];
  GstRTSPStatusCode res;
  _GstApExRAOP *conn;

  conn = (_GstApExRAOP *) con;

  v = GST_APEX_RAOP_VOLUME_MIN + (GST_APEX_RAOP_VOLUME_MAX -
      GST_APEX_RAOP_VOLUME_MIN) * volume / 100.;
  sprintf (vol, "volume: %d.000000\r\n", v);

  sprintf (creq, "%s\r\n", vol);

  sprintf (hreq,
      "SET_PARAMETER rtsp://%s/%s RTSP/1.0\r\n"
      "CSeq: %d\r\n"
      "Client-Instance: %s\r\n"
      "User-Agent: %s\r\n"
      "Session: %s\r\n"
      "Content-Type: text/parameters\r\n"
      "Content-Length: %u\r\n",
      conn->host,
      conn->url_abspath,
      ++conn->cseq, conn->cid, conn->ua, conn->session, (guint) strlen (creq)
      );

  req = g_strconcat (hreq, "\r\n", creq, NULL);

  if (gst_apexraop_send (conn->ctrl_sd, req, strlen (req)) <= 0) {
    g_free (req);
    return GST_RTSP_STS_GONE;
  }

  g_free (req);

  if (gst_apexraop_recv (conn->ctrl_sd, hreq,
          GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
    return GST_RTSP_STS_GONE;

  {
    int tmp;
    sscanf (hreq, "%*s %d", &tmp);
    res = (GstRTSPStatusCode) tmp;
  }

  return res;
}

/* raop apex raw data alac encapsulation, encryption and emission, http://wiki.multimedia.cx/index.php?title=Apple_Lossless_Audio_Coding */
static void inline
gst_apexraop_write_bits (guchar * buffer, int data, int numbits,
    int *bit_offset, int *byte_offset)
{
  const static guchar masks[] =
      { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF };

  if (((*bit_offset) != 0) && (((*bit_offset) + numbits) > 8)) {
    gint numwritebits;
    guchar bitstowrite;

    numwritebits = 8 - (*bit_offset);
    bitstowrite =
        (guchar) ((data >> (numbits - numwritebits)) << (8 - (*bit_offset) -
            numwritebits));
    buffer[(*byte_offset)] |= bitstowrite;
    numbits -= numwritebits;
    (*bit_offset) = 0;
    (*byte_offset)++;
  }

  while (numbits >= 8) {
    guchar bitstowrite;

    bitstowrite = (guchar) ((data >> (numbits - 8)) & 0xFF);
    buffer[(*byte_offset)] |= bitstowrite;
    numbits -= 8;
    (*bit_offset) = 0;
    (*byte_offset)++;
  }

  if (numbits > 0) {
    guchar bitstowrite;
    bitstowrite =
        (guchar) ((data & masks[numbits]) << (8 - (*bit_offset) - numbits));
    buffer[(*byte_offset)] |= bitstowrite;
    (*bit_offset) += numbits;
    if ((*bit_offset) == 8) {
      (*byte_offset)++;
      (*bit_offset) = 0;
    }
  }
}

guint
gst_apexraop_write (GstApExRAOP * con, gpointer rawdata, guint length)
{
  guchar *buffer, *frame_data;
  gushort len;
  gint bit_offset, byte_offset, i, out_len, res;
  EVP_CIPHER_CTX aes_ctx;
  _GstApExRAOP *conn = (_GstApExRAOP *) con;
  const int frame_header_size = conn->generation == GST_APEX_GENERATION_ONE
      ? GST_APEX_RAOP_FRAME_HEADER_SIZE : GST_APEX_RTP_FRAME_HEADER_SIZE;

  buffer =
      (guchar *) g_malloc0 (frame_header_size +
      GST_APEX_RAOP_ALAC_HEADER_SIZE + length);

  if (conn->generation == GST_APEX_GENERATION_ONE) {
    g_assert (frame_header_size == GST_APEX_RAOP_FRAME_HEADER_SIZE);
    memcpy (buffer, GST_APEX_RAOP_FRAME_HEADER, frame_header_size);

    len = length + frame_header_size + GST_APEX_RAOP_ALAC_HEADER_SIZE - 4;

    buffer[2] = len >> 8;
    buffer[3] = len & 0xff;
  } else {
    /* Gen. 2 uses RTP-like header (RFC 3550). */
    short network_seq_num;
    int network_timestamp, unknown_const;
    static gboolean first = TRUE;

    buffer[0] = 0x80;
    if (first) {
      buffer[1] = 0xe0;
      first = FALSE;
    } else
      buffer[1] = 0x60;

    network_seq_num = htons (conn->rtp_seq_num++);
    memcpy (buffer + 2, &network_seq_num, 2);

    network_timestamp = htons (conn->rtp_timestamp);
    memcpy (buffer + 4, &network_timestamp, 4);
    conn->rtp_timestamp += GST_APEX_RAOP_V2_SAMPLES_PER_FRAME;

    unknown_const = 0xdeadbeef;
    memcpy (buffer + 8, &unknown_const, 4);
  }

  bit_offset = 0;
  byte_offset = 0;
  frame_data = buffer + frame_header_size;

  gst_apexraop_write_bits (frame_data, 1, 3, &bit_offset, &byte_offset);        /* channels, 0 mono, 1 stereo */
  gst_apexraop_write_bits (frame_data, 0, 4, &bit_offset, &byte_offset);        /* unknown */
  gst_apexraop_write_bits (frame_data, 0, 8, &bit_offset, &byte_offset);        /* unknown (12 bits) */
  gst_apexraop_write_bits (frame_data, 0, 4, &bit_offset, &byte_offset);
  gst_apexraop_write_bits (frame_data, 0, 1, &bit_offset, &byte_offset);        /* has size flag */
  gst_apexraop_write_bits (frame_data, 0, 2, &bit_offset, &byte_offset);        /* unknown */
  gst_apexraop_write_bits (frame_data, 1, 1, &bit_offset, &byte_offset);        /* no compression flag */

  for (i = 0; i < length; i += 2) {
    gst_apexraop_write_bits (frame_data, ((guchar *) rawdata)[i + 1], 8,
        &bit_offset, &byte_offset);
    gst_apexraop_write_bits (frame_data, ((guchar *) rawdata)[i], 8,
        &bit_offset, &byte_offset);
  }

  EVP_CIPHER_CTX_init (&aes_ctx);
  EVP_CipherInit_ex (&aes_ctx, EVP_aes_128_cbc (), NULL, conn->aes_ky,
      conn->aes_iv, AES_ENCRYPT);
  EVP_CipherUpdate (&aes_ctx, frame_data, &out_len, frame_data, /*( */
      GST_APEX_RAOP_ALAC_HEADER_SIZE +
      length /*) / AES_BLOCK_SIZE * AES_BLOCK_SIZE */ );
  EVP_CIPHER_CTX_cleanup (&aes_ctx);

  res =
      gst_apexraop_send (conn->data_sd, buffer,
      frame_header_size + GST_APEX_RAOP_ALAC_HEADER_SIZE + length);

  g_free (buffer);

  return (guint) ((res >=
          (frame_header_size +
              GST_APEX_RAOP_ALAC_HEADER_SIZE)) ? (res -
          frame_header_size - GST_APEX_RAOP_ALAC_HEADER_SIZE) : 0);
}

/* raop apex buffer flush */
GstRTSPStatusCode
gst_apexraop_flush (GstApExRAOP * con)
{
  gchar hreq[GST_APEX_RAOP_HDR_DEFAULT_LENGTH];
  GstRTSPStatusCode res;
  _GstApExRAOP *conn;

  conn = (_GstApExRAOP *) con;

  sprintf (hreq,
      "FLUSH rtsp://%s/%s RTSP/1.0\r\n"
      "CSeq: %d\r\n"
      "Client-Instance: %s\r\n"
      "User-Agent: %s\r\n"
      "Session: %s\r\n"
      "RTP-Info: seq=%d;rtptime=%d\r\n"
      "\r\n",
      conn->host,
      conn->url_abspath,
      ++conn->cseq,
      conn->cid,
      conn->ua, conn->session, conn->rtp_seq_num, conn->rtp_timestamp);

  if (gst_apexraop_send (conn->ctrl_sd, hreq, strlen (hreq)) <= 0)
    return GST_RTSP_STS_GONE;

  if (gst_apexraop_recv (conn->ctrl_sd, hreq,
          GST_APEX_RAOP_HDR_DEFAULT_LENGTH) <= 0)
    return GST_RTSP_STS_GONE;

  {
    int tmp;
    sscanf (hreq, "%*s %d", &tmp);
    res = (GstRTSPStatusCode) tmp;
  }

  return res;
}
