/*
	Auther:		Satoshi Yasuda	7m3tjz/ad6gz
	Date:		2014.01.19

*/

#include	<stdio.h>
#include	<string.h>
#include	<netinet/in.h>
#include	<sys/ipc.h>
#include	<sys/msg.h>
#include	<mqueue.h>
#include	"dsgwd_pi.h"
#include	"node_adapter.h"
#include	"node.h"

char	headerRead;
char	header_gen;
char	SendHeader;
char	SendToInet;

unsigned int	Packet_ID;
extern	struct usb_dev_handle *udev;	
extern	mqd_t	rf_qid;
extern	mqd_t	inet_qid;

extern	char	ReSyncFrame[3];
extern	char	NullVoice0[12];
extern	char	NullVoice1[12];
extern	char	NullVoice_ID31[9];
extern	char	LastFrame0[6];
extern	char	LastFrame1[6];
extern	char	respFlags;
char	SlowData[6];
char	voice[12];

char 	LastFrameCheckRx[6];
unsigned char	Packet_Seq;
unsigned char	Packet_Seq_Save;
char	COS_On;


char	JitterBuffer[JitterBufferSize][12];		
char	JitterBufferPnt;
char	CurJitterBufferPnt;
char	VoicePacketSW;
extern	int	voice_pnt;


void	from_rig(void)
{
	int	length;
	int	ret;
	int	i;
	char	rig_buffer[32];
	char	status;
	char	l;
	char	msg[20];

	/* rf header read */
	if (!headerRead)
	{
		ret = usb_control_msg (udev, 0xC0, GET_HEADER, 0, 0, rf_header.header1, 32, 100);
        	if (ret != 32)
		{
			return;  /*RF header read? */
		}

        	usb_control_msg (udev, 0xC0, GET_HEADER, 0, 0, &rf_header.header2, 9, 100);
  		usb_control_msg (udev, 0xC0, GET_AD_STATUS, 0, 0, &status, 1, 100);

		headerRead = TRUE;
		SendHeader = TRUE;
		SendToInet = TRUE;
		voice_pnt = 0;

	} else {
		/* rf voice read */
		length = usb_control_msg (udev, 0xC0, GET_DATA, 0, 0, rig_buffer, 32, 100);
		if ((length <= 32 ) && (length > 0))
		{
			for (i = 0 ; i < length ; i++)
			{
				voice[voice_pnt] = rig_buffer[i];
				voice_pnt++;
				LastFrameCheckRx[0] = LastFrameCheckRx[1]; 
				LastFrameCheckRx[1] = LastFrameCheckRx[2]; 
				LastFrameCheckRx[2] = LastFrameCheckRx[3]; 
				LastFrameCheckRx[3] = LastFrameCheckRx[4]; 
				LastFrameCheckRx[4] = LastFrameCheckRx[5];
				LastFrameCheckRx[5] = rig_buffer[i];
 
				if (!memcmp(LastFrameCheckRx, LastFrame0, 6))
				{
					dv_frame.B_header.seq = Packet_Seq | 0x40;
					send_voice_queue();
					Packet_Seq++;
					if (Packet_Seq > 20) Packet_Seq = 0;
					headerRead = FALSE;
					SendHeader = FALSE;
					COS_On = FALSE;
					sprintf (msg,"CALLED FROM %8.8s",&rf_header.MyCall);
					if (SendToInet) BeepSend(rf_header.MyCall, respFlags);
					return;
				}

				if (voice_pnt == 12)
				{
					if (!memcmp (&voice[9], ReSyncFrame, 3)) Packet_Seq = 0;
					dv_frame.B_header.seq = Packet_Seq;
					if (Packet_Seq != 0)
					{
						if (Packet_Seq % 2)
						{
							memcpy (SlowData, &voice[9], 3);
							SlowData[0] ^= 0x70;
							SlowData[1] ^= 0x4f;
							SlowData[2] ^= 0x93;
						} else {
							memcpy (&SlowData[3], &voice[9], 3);
							SlowData[3] ^= 0x70;
							SlowData[4] ^= 0x4f;
							SlowData[5] ^= 0x93;
							if ((SlowData[0] & 0xf0) == 0x30) DprsData (SlowData);
						}
					}
					if (((BitsCheck((char *)voice, NullVoice0, 9) < MaxErrorBit) 
						|| (BitsCheck((char *)voice, NullVoice_ID31, 9) < MaxErrorBit)) 
						&& SendHeader)
					{
						SendToInet = FALSE;
						SendHeader = FALSE;	/* header sending switch */
					}
					send_voice_queue();
					Packet_Seq++;
					if (Packet_Seq > 20) Packet_Seq = 0;
					voice_pnt = 0;
				}
			}
		}
		else if (length == 0)
                {
                        usb_control_msg (udev, 0xC0, GET_AD_STATUS, 0, 0, &status, 1, 100);
                        if (!(status & COS_OnOff))
                        {
                                headerRead = FALSE;
                                COS_On = FALSE;
                                header_gen = FALSE;
                                SendHeader = FALSE;
                                return;
                        }
                }
		usb_control_msg (udev, 0xC0, GET_AD_STATUS, 0, 0, &status, 1, 100);
		if (status & HeaderDecodeDone)
		{
				printf ("debug HeaderDecodeDone\n");
				headerRead = FALSE;
				COS_On = FALSE;
				header_gen = FALSE;
				SendHeader = FALSE;
				return;
		}
	}
}

void	send_voice_queue(void) 	/* read from rig (DV packet) */
{
	extern	char voice[12];
	if (SendHeader)
	{
				Packet_Seq_Save = dv_frame.B_header.seq;
				send_header_queue();
				SendHeader = FALSE;
				COS_On = TRUE;
				dv_frame.B_header.seq = Packet_Seq_Save & 0x40;
	}
	memcpy ((char *)dv_frame.ID,  "DSVT" ,4);
	dv_frame.flags[0] = 0x20;
	dv_frame.flags[1] = 0x00;
	dv_frame.reserve[0] = 0x81;
	dv_frame.reserve[1] = 0x00;
	dv_frame.B_header.B_ID = 0x20;
	dv_frame.B_header.DestID = 0x00;
	dv_frame.B_header.SrcID = 0x01;
	dv_frame.B_header.SrcTermID = 0x02;
//	dv_frame.B_header.seq = Packet_Seq;
	dv_frame.B_header.PacketID[0] = (Packet_ID >> 8) & 0xff;
	dv_frame.B_header.PacketID[1] = Packet_ID & 0xff;
	memcpy ((char *)dv_frame.voice.voice, (char *)voice, 12);
	if (SendToInet) mq_send (rf_qid, (char *)&dv_frame, sizeof(dv_frame), 1);
	if (repeater_mode)
	{
		mq_send (inet_qid, (char *)&dv_frame, sizeof(dv_frame), 1);
	}
}

void	send_header_queue(void) 	/* read from rig (DV packet) */
{

		/* RF header send */
		memcpy ((char *)dv_frame.ID,  "DSVT" ,4);
		dv_frame.flags[0] = 0x10;
		dv_frame.flags[1] = 0x00;
		dv_frame.reserve[0] = 0x81;
		dv_frame.reserve[1] = 0x00;
		dv_frame.B_header.B_ID = 0x20;
		dv_frame.B_header.DestID = 0x00;
		dv_frame.B_header.SrcID = 0x01;
		dv_frame.B_header.SrcTermID = 0x02;
		dv_frame.B_header.seq = 0x80;
		Packet_ID = rand();
		dv_frame.B_header.PacketID[0] = (Packet_ID >> 8) & 0xff;
		dv_frame.B_header.PacketID[1] = Packet_ID & 0xff;
		Packet_Seq = 0;

		memcpy ((char *)&dv_frame.header, (char *)&rf_header, 41);
		memcpy ((char *)&dv_frame.header.Rpt1Call, client_call, 8);
		if (SendToInet) mq_send (rf_qid, (char *)&dv_frame, sizeof(dv_frame), 1);

		if (repeater_mode)
		{
			dv_frame.header.flags[0] = 0x00;
			mq_send (inet_qid, (char *)&dv_frame, sizeof(dv_frame), 1);
		}
}

int	BitsCheck(char pattern1[], char pattern2[], int cnt)
{
	char	temp;
	int	i, j, k;
	
	k = 0;
	for (i = 0 ; i < cnt ; i++)
	{
		temp = pattern1[i] ^ pattern2[i];
		for (j = 0 ; j < 8 ; j++)
		{
			if (temp & (0x80 >> i)) k++; 
		}
	}
	return k;
}

