/*
 * Copyright 2008-2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <sys/types.h>  /* for type definitions */
#include <sys/socket.h> /* for socket API calls */
#include <sys/select.h>
#include <netinet/in.h> /* for address structs */
#include <arpa/inet.h>  /* for sockaddr_in */
#include <stdio.h>      /* for printf() and fprintf() */
#include <stdlib.h>     /* for atoi() */
#include <string.h>     /* for strlen() */
#include <unistd.h>     /* for close() */
#include <time.h>
#include <fcntl.h>

#define MAX_LEN  2048   /* maximum receive string size */
#define MIN_PORT 1024   /* minimum port allowed */
#define MAX_PORT 65535  /* maximum port allowed */

#define RTP_VERSION          2  /* version as defined in RFC-3550 */
#define RTP_HDR_SIZE        12
#define TS_PACKET_SIZE     188

typedef enum {
  PACKET_HDR_FORMAT_UNKNOWN = 0,  // not RTP and not plain TS, probably
                                  // corrupted
  PACKET_HDR_FORMAT_NONE,         // plain TS, no extra payload header
  PACKET_HDR_FORMAT_RTP           // RTP header
} packet_hdr_format_t;

const char *get_hdr_format_str(packet_hdr_format_t hdr) {
  switch(hdr) {
    case PACKET_HDR_FORMAT_RTP:
      return "RTP";
    case PACKET_HDR_FORMAT_NONE:
      return "Plain-TS";
    case PACKET_HDR_FORMAT_UNKNOWN:
    default:
      return "Unknown";
  }
}

void printhelp(char *argv[]) {
  fprintf(stderr,
          "Usage: \n"
          "%s <IP> <Port> [-d <paks-per-dot>] [-n <npaks>] [-t <timeout>]\n"
          "               [-c <ts-file>] [-u <udp-file>]\n"
          "    paks-per-dot: print a dot every time this number of packets\n"
          "             is received - disable with 0\n"
          "    npaks: exit with status 0 after this many packets have been\n"
          "             received\n"
          "    timeout: exit with error status after this many seconds have\n"
          "             elapsed --\n"
          "             exit with status 2 if 0 packets received \n"
          "             exit with status 1 if some packets received\n"
          "    ts-file: save received TS packets (i.e., UDP or RTP payload)\n"
          "             into this file\n"
          "    udp-file: save UDP payload into this file, with each packet\n"
          "             prefixed by its length: <len1> + <UDP-payload1>,\n"
          "             <len2> + <udp-payload2>, ..\n"
          "             This allows to identify individual UDP packet\n"
          "             boundaries.\n"
          "\n"
          " Note: Presence of RTP headers is handled automatically and the\n"
          "       headers are removed for the ts-file output but retained in\n"
          "       the udp-file."
          "\n"
          "Examples:\n"
          "  %s 225.0.0.100 2000 -d 100\n"
          "       run forever monitoring this multicast stream \n"
          "       printing a dot for every 100 packets\n"
          "  %s 225.0.0.100 2000 -d 0 -n 100 -t 60 -c cap.ts\n"
          "       test this multicast stream, printing no dots,\n"
          "       returning an error if 100 packets are not received in\n"
          "       60 seconds and storing the captured data in cap.ts\n",
          argv[0],argv[0],argv[0]);
}

static inline packet_hdr_format_t get_packet_hdr_format(uint8_t first_byte,
                                                        int size) {
  int has_rtp = (first_byte >> 6) == RTP_VERSION &&
    ((size - RTP_HDR_SIZE) % TS_PACKET_SIZE) == 0;
  int is_plain_ts = first_byte == 0x47 && (size % TS_PACKET_SIZE) == 0;

  if (has_rtp)
    return PACKET_HDR_FORMAT_RTP;
  else if (is_plain_ts)
    return PACKET_HDR_FORMAT_NONE;
  return PACKET_HDR_FORMAT_UNKNOWN;
}


int main(int argc, char *argv[]) {

  int sock;                     /* socket descriptor */
  int flag_on = 1;              /* socket option flag */
  int recv_buf_size = 1024*1024;/* maximum socket receive buffer in bytes */
  struct sockaddr_in mc_addr;   /* socket address structure */
  char recvBuff[MAX_LEN+1];     /* buffer to receive string */
  int recv_len;                 /* length of string received */
  struct ip_mreq mc_req;        /* multicast request structure */
  char* mc_addr_str;            /* multicast IP address */
  unsigned int mc_port;       /* multicast port */
  struct sockaddr_in from_addr; /* packet source */
  unsigned int from_len;        /* source addr length */
  int packets_per_dot=1;
  int num_packets=0;
  int npacketsLimit=0;
  int timeoutSecs=0;
  const char* ts_filename = NULL, *udp_filename = NULL;
  int fd_ts = -1, fd_udp = -1;

  /* for select() */
  fd_set socks;
  int readSocks=0;
  struct timeval timeout;

  int opt;
  while ((opt = getopt(argc, argv, "?hd:n:t:c:u:")) != -1) {
    switch (opt) {
    case '?':
    case 'h':
      printhelp(argv);
      exit(0);
    case 'd':
      packets_per_dot = atoi(optarg);
      if ( packets_per_dot < 0 ) {
        fprintf(stderr,"invalid value for packets_per_dot");
        printhelp(argv);
        exit(4);
      }
      break;
    case 'n':
      npacketsLimit=atoi(optarg);
      if ( npacketsLimit < 0 ) {
        fprintf(stderr,"invalid value for npackets");
        printhelp(argv);
        exit(4);
      }
      break;
    case 't':
      timeoutSecs=atoi(optarg);
      if ( timeoutSecs < 0 ) {
        fprintf(stderr,"invalid value for timeoutSecs");
        printhelp(argv);
        exit(4);
      }
      break;
    case 'c':
      ts_filename = optarg;
      break;
    case 'u':
      udp_filename = optarg;
      break;
    }
  }

  if ( optind + 2 != argc ) {
    fprintf(stderr, "Missing either <IP> or <Port>\n");
    printhelp(argv);
    exit(4);
  }

  mc_addr_str = argv[optind];        /* multicast ip address */
  mc_port = atoi(argv[optind + 1]);  /* multicast port number */
  /* validate the port range */
  if ((mc_port < MIN_PORT) || (mc_port > MAX_PORT)) {
    fprintf(stderr, "Invalid port number argument %d.\n", mc_port);
    fprintf(stderr, "Valid range is between %d and %d.\n", MIN_PORT, MAX_PORT);
    exit(4);
  }

  printf("Running with these configs:\nmcast-addr:%s:%d paks-per-dot:%d "
         "npaklimit:%d timeout:%d ts_filename:%s updFilename:%s\n", mc_addr_str,
         mc_port, packets_per_dot, npacketsLimit, timeoutSecs, ts_filename,
         udp_filename);

  if (ts_filename) {
    fd_ts = open(ts_filename, O_WRONLY | O_EXCL | O_CREAT, 0666);
    if (fd_ts < 0) {
      perror("Error opening <ts_filename>");
    }
  }
  if (udp_filename) {
    fd_udp = open(udp_filename, O_WRONLY | O_EXCL | O_CREAT, 0666);
    if (fd_udp < 0) {
      perror("Error opening <udp_filename>");
    }
  }

  /* create socket to join multicast group on */
  if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    perror("socket() failed");
    exit(4);
  }

  /* set reuse port to on to allow multiple binds per host */
  if ((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag_on,
                  sizeof(flag_on))) < 0) {
    perror("setsockopt() failed");
    exit(4);
  }

  if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &recv_buf_size,
                  sizeof(recv_buf_size)) != 0 ) {
    perror("setsockopt() failed");
    exit(4);
  }

  /* construct a multicast address structure */
  memset(&mc_addr, 0, sizeof(mc_addr));
  mc_addr.sin_family      = AF_INET;
  mc_addr.sin_addr.s_addr = inet_addr(mc_addr_str);
  mc_addr.sin_port        = htons(mc_port);

  /* bind to multicast address to socket */
  if ((bind(sock, (struct sockaddr *) &mc_addr,
            sizeof(mc_addr))) < 0) {
    perror("bind() failed");
    exit(4);
  }

  /* construct an IGMP join request structure */
  mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str);
  mc_req.imr_interface.s_addr = htonl(INADDR_ANY);

  /* send an ADD MEMBERSHIP message via setsockopt */
  if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                  (void*) &mc_req, sizeof(mc_req))) < 0) {
    perror("setsockopt() failed");
    exit(4);
  }
  /* clear the receive buffers & structs */
  memset(recvBuff, 0, sizeof(recvBuff));
  from_len = sizeof(from_addr);
  memset(&from_addr, 0, from_len);

  time_t startTime=time(NULL);
  packet_hdr_format_t last_hdr_fmt = PACKET_HDR_FORMAT_UNKNOWN, cur_hdr_fmt;

  for (;;) {          /* loop forever */
    FD_ZERO(&socks);
    FD_SET(sock,&socks);
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    readSocks=select(sock+1,&socks,NULL,NULL,&timeout);

    if ( readSocks > 0 ) {

      /* read one UDP packet */
      if ((recv_len = recvfrom(sock, recvBuff, MAX_LEN, 0,
                               (struct sockaddr*)&from_addr, &from_len)) < 0) {
        perror("recvfrom() failed");
        exit(4);
      }

      num_packets++;
      if (packets_per_dot>0 && ( num_packets % packets_per_dot == 0 ) ) {
        putchar('.');
        if ( (num_packets/packets_per_dot)%80==0)
          putchar('\n');
        fflush(stdout);
      }
      if (npacketsLimit > 0 && num_packets >= npacketsLimit) {
        printf("exiting: %d packets received\n",num_packets);
        exit(0);
      }

      // handle RTP header
      cur_hdr_fmt = get_packet_hdr_format((uint8_t)recvBuff[0], recv_len);
      if (last_hdr_fmt != cur_hdr_fmt) {
        printf("Payload format changed:%s -> %s\n",
               get_hdr_format_str(last_hdr_fmt),
               get_hdr_format_str(cur_hdr_fmt));
        last_hdr_fmt = cur_hdr_fmt;
      }
      char *ts_payload_ptr = recvBuff;
      int ts_payload_len = recv_len;
      if (cur_hdr_fmt == PACKET_HDR_FORMAT_RTP) {
        // strip RTP header
        ts_payload_ptr += RTP_HDR_SIZE;
        ts_payload_len -= RTP_HDR_SIZE;
      }

      if (fd_ts >= 0) {
        /* write TS packets */
        int l = write(fd_ts, ts_payload_ptr, ts_payload_len);
        if (l < ts_payload_len) {
          fprintf(stderr, "Warning-Wrote only %d/%d ts-bytes, stop writing "
                  "ts-file!\n", l, ts_payload_len);
          close(fd_ts);
          fd_ts = -1;
        }
      }
      if (fd_udp >= 0) {
        /* write payload length */
        int l = write(fd_udp, &recv_len, sizeof(recv_len));
        if (l < (int)sizeof(recv_len)) {
          fprintf(stderr, "Warning-Wrote only %d/%d bytes, stop writing "
                  "udp-file!\n", l, (int)sizeof(recv_len));
          close(fd_udp);
          fd_udp = -1;
        } else {
          /* write payload */
          l = write(fd_udp, recvBuff, recv_len);
          if (l < recv_len) {
            fprintf(stderr, "Warning-Wrote only %d/%d udp-bytes, stop writing "
                    "udp-file!\n", l, recv_len);
            close(fd_udp);
            fd_udp = -1;
          }
        }
      }
    } else if ( readSocks == 0 ) {
      /* timeout */
      if (timeoutSecs>0 && time(NULL) >= startTime+timeoutSecs ){
        printf("timeout: %d packets received\n",num_packets);
        if ( num_packets > 0){
          exit(1);
        } else {
          exit(2);
        }
      }

    } else if (readSocks < 0) {
      perror("select");
      exit(4);
    }
  }
}
