/*
 * rtsp.h
 * 
 * Author: Marc Unangst
 */
/*
 * Copyright (c) of Carnegie Mellon University, 1996,1997,1998,1999.
 *
 * Permission to reproduce, use, and prepare derivative works of
 * this software for internal use is granted provided the copyright
 * and "No Warranty" statements are included with all reproductions
 * and derivative works. This software may also be redistributed
 * without charge provided that the copyright and "No Warranty"
 * statements are included in all redistributions.
 *
 * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
 * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
 * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
 * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
 * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
 * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
 * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 */


#ifndef _RTSP_H_INCLUDED
#define _RTSP_H_INCLUDED

#include <nasd/nasd_options.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <nasd/nasd_threadstuff.h>
#include <nasd/video/flex-internal.h>

/* return values from yylex() */
#define RTSP_OK			0
#define RTSP_UNIMPLEMENTED	1
#define RTSP_BAD_REQUEST	2
#define RTSP_EOF		(-1)

#define RTSP_MAJOR_VER		0
#define RTSP_MINOR_VER		6

#define CMD_NULL		0
#define CMD_CLOSE		1
#define CMD_TXABORT		2
#define CMD_PAUSE               3
#define CMD_UNPAUSE             4

#define NASD_MERGE_LOCK_COMMAND(c)	NASD_LOCK_MUTEX((c)->cmd_mutex)
#define NASD_MERGE_WAIT_COMMAND(c)	NASD_WAIT_COND((c)->cmd_cv, (c)->cmd_mutex)
#define NASD_MERGE_UNLOCK_COMMAND(c)	NASD_UNLOCK_MUTEX((c)->cmd_mutex)

struct clientinfo {
  int cur_seq;			/* RTSP sequence number */
  int fd;			/* fd for RTSP socket */
  struct sockaddr_in saddr;	/* address of client (port of RTSP socket) */
  struct sockaddr_in maddr;	/* address of client (port of movie socket) */
  struct streaminfo *sinf;	/* client's stream info */
  int my_flow;			/* flow assigned to this client */
  nasd_thread_t ctrl_thread;	/* control thread ID */
  nasd_thread_t merge_thread;	/* merging/data receive thread ID */
  nasd_thread_t tx_thread;	/* data transmit thread ID */
  struct clientinfo *next;
  struct clientinfo *prev;
  /* FIXME eventually this should be a queue */
  NASD_DECLARE_MUTEX(cmd_mutex)
  NASD_DECLARE_COND(cmd_cv)
  int cmd;
};

enum cmd_type {
  HELLO,
  GET,
  SETUP,
  PLAY,
  PAUSE,
  /* UNPAUSE,  */
  CLOSE,
  REDIRECT,
  SESSION,
  RECORD,
  BYE,
  SET_PARAMETER,
  GET_PARAMETER
};

enum hdr_type {
  Transport,
  Session,
  Content_Length,
  Require
};

struct header {
  char *name;
  enum hdr_type type;
  struct header *next;
  /* header-dependent info follows here */
};

struct header_transport {
  char *name;
  enum hdr_type type;
  struct header *next;
  enum {
    tcp,
    udp
  } transport_proto;
  enum {
    rtp,
    x_raw
  } upper_layer;
  char is_multicast;
  char is_compressed;
  char is_interleaved;
  short ttl;
  short port;
  int ssrc;
};

struct header_require {
  char *name;
  enum hdr_type type;
  struct header *next;
  char *reason;
};

struct rtsp_cmd {
  enum cmd_type reqcmd;
  char *path;
  int seqnum;
  struct header *hdrs;
};

struct rtsp_resp {
  int status;
  char *reason;
  int seqnum;
  struct header *hdrs;
};

extern struct rtsp_cmd *rtspLexCmd;
extern int RtspPortNum;
NASD_DECLARE_EXTERN_MUTEX(lexerMutex)

/* rtsp.c */
extern int rtspNewHeader(struct header **, struct header *);
extern int rtspGetLexer(YY_BUFFER_STATE);
extern int rtspFreeLexer(void);
extern int rtspGetCommand(int fd, char *buf, int buflen, int *len);
extern int rtspHandleCommand(struct clientinfo *, struct rtsp_cmd *);
extern int rtspSendReply(struct clientinfo *, struct rtsp_resp *);
extern int rtspOutputHeader(int, struct header *);
extern int rtspHandleUnimpl(struct clientinfo *cinf, struct rtsp_cmd *cmd);
extern int rtspHandleSetup(struct clientinfo *cinf, struct rtsp_cmd *cmd);
extern int rtspHandlePlay(struct clientinfo *cinf, struct rtsp_cmd *cmd);
extern int rtspHandleClose(struct clientinfo *cinf, struct rtsp_cmd *cmd);
extern int rtspHandlePause(struct clientinfo *cinf, struct rtsp_cmd *cmd);

#endif
