/*
	Auther		Satoshi Yasuda	7m3tjz/ad6gz
	Date		2014.01.20
*/

#define FALSE           0
#define TRUE            1
#define MaxErrorBit     3
#define RF              1
#define INET            2
#define JitterBufferSize        21


void    from_node(void);
void    send_voice_queue(void);
void    send_header_queue(void);
void    BeepSend (char callsign[], char flags);
int     BitsCheck(char pattern1[], char pattern2[], int cnt);
void    Ptt_Off(void);
void    send_header_USB(char pkt[]);
void    send_voice_USB (char pkt[], char seq);
void    JitterBufferSend (void);
void    JitterBufferSave (char VoicePacket[], unsigned char sequence);
void    from_inet(void);
void	ConSend(void);


#define timercmp(a, b, CMP) \
 (((a)->tv_sec == (b)->tv_sec) ? \
  ((a)->tv_usec CMP (b)->tv_usec) : \
  ((a)->tv_sec CMP (b)->tv_sec))


// 足し算マクロ
#define timeradd(a, b, result) \
  do { \
    (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
    (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
    if ((result)->tv_usec >= 1000000) \
      { \
        ++(result)->tv_sec; \
        (result)->tv_usec -= 1000000; \
      } \
  } while (0)

// 引き算マクロ
#define timersub(a, b, result) \
  do { \
    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
    if ((result)->tv_usec < 0) { \
      --(result)->tv_sec; \
      (result)->tv_usec += 1000000; \
    } \
  } while (0)



/* reqType	*/
#define		NoEntry		0x00
#define		ReqConnect	0x01
#define		Ack		0x02
#define		Nak		0x03		/* Busy	*/
#define		NoRoute		0x04
#define		ReqEnd		0xff


/* protocol	*/
#define		ICOM	0x00
#define		DPlus	0x01
#define		DCS	0x02
#define		G3	0x03	/* New System */


#define	RespNULL	0x00
#define	RespAck		0x03
#define	RespBusy	0x02
#define RespNoRoute	0x01

#define	RF	1
#define	INET	2
#define	STREAM_ID	"DSVT"
#define	TRUE	1
#define	FALSE	0

struct	repMsg
{
	unsigned char		reqType;		/* 0x00: NoEntry    */
							/* 0x01: ReqConnect */
							/* 0x02: Ack	    */
							/* 0x03: Nak	    */
							/* 0xff: ReqEnd     */
	union {
		struct
		{
        		char            protocol;       /* 0: ICOM   */
                      			                /* 1: DPlus  */
                                        		/* 2: DCS    */
							/* 3: G3     */
                        char            Rpt2Call[8];
                        char            Rpt1Call[8];
                        char            YourCall[8];
                        char            MyCall[8];
			char		trustname[8];
			struct	in_addr	ip;
			in_port_t	port;
			unsigned char	PacketID[2];
		} reqConnect;
		struct
		{
                        char            protocol;       /* 0: ICOM   */
                                                        /* 1: DPlus  */
                                                        /* 2: DCS    */
							/* 3: G3     */
                        char            Rpt2Call[8];
                        char            Rpt1Call[8];
                        char            YourCall[8];
                        char            MyCall[8];
                        char            reserve[7];
			unsigned char	RespFlags;
			struct	in_addr	ip;
			in_port_t	port;
			unsigned char	PacketID[2];
		} ackConnect;
	};
};


struct packet{
	unsigned char	ID[4];				/* DSVT */
	unsigned char	flags[2];
	unsigned char	reserve[2];
	struct
	{
		unsigned char	B_ID;			/* 0x20 */
		unsigned char	DestID;			/* 0x00 */
		unsigned char	SrcID;			/* 0x01 */
		unsigned char	SrcTermID;		/* 0x02 */
		unsigned char	PacketID[2];
		unsigned char	seq;
	} B_header;
	union {
                        struct
                        {
                                unsigned char   flags[3];
                                char            Rpt2Call[8];
                                char            Rpt1Call[8];
                                char            YourCall[8];
                                char            MyCall[8];
                                char            Mycall2[4];
                                unsigned char   crc[2];
                        } header;
			struct
			{
				char	voice[9];
				char	slowdata[3];
			} voice;
			char	lastframe[15];
	};
} ;

struct	{
	struct	in_addr	ip;
	in_port_t	port;
	struct	packet	dv;
} RelayPacket;

struct	shm_form {
        unsigned char    type;          /* 0x00 not use         */
                                        /* 0x01 リクエスト　    */
                                        /* 0x02 リプライ        */
                                        /* 0x03 未登録          */
                                        /* 0x04 ポート登録      */
                                        /* 0xff 削除            */
        char    protocol;
	char	dstRep[8];
	char	Rep2Call[8];
	char	Rep1Call[8];
	char	dstCall[8];
	char	srcCall[8];
	in_port_t	srcPort;
        struct  in_addr srcIP;
	unsigned char	PacketID[2];
};


unsigned int	trust_port;
unsigned int	client_port;
unsigned int	trust_db_port;
int		cmdmode;
char		client_call[8];
char		client_password[64];
char		TrustDomainName[128];
char		TrustDbDomainName[128];
char		repeater_mode;

struct	packet	dv_frame;

unsigned	int	NodeVendorID;
unsigned	int	NodeProductID;
