/*							*/
/*	D-STAR room client Program               	*/
/*      	    V00.05  09/29/2011                  */
/*  				Satoshi Yasuda		*/
/*				7m3tjz/ad6gz		*/
/*                              	                */

#define	header_type  0x10
#define	dv_type	0x20

#include "TCPIP Stack/TCPIP.h"
#include "TCPIP Stack/BerkeleyAPI.h"

#include "FreeRTOS.h"
#include "queue.h"
#include "lcd.h"

#include "../USB/usb_host_local.h"
#include "node.h"

typedef struct{
	char	req_id[2];
	char	flags[2];
	char	PicVer[2];
	char	reserve[2];
	char	req_callsign[8];
	char	zone[8];
	char	area[8];
	unsigned long	ip_address;
	unsigned int	ssn;
	unsigned int	port;
}	call_table;

typedef struct{		
	unsigned char	id[4];
	unsigned char	flags[2];
	unsigned char	reserve[2];
	unsigned char	type_id;
	unsigned char	dest_repeater_id;
	unsigned char	send_repeater_id;
	unsigned char	send_terminal_id;
	unsigned char	seq_high;
	unsigned char	seq_low;
	unsigned char	control;
	unsigned char	body[41];
} packet;

void	send_dv_callEntry (call_table call_pkt);
void	send_dv_header (packet pkt);
void	send_dv_packet (packet pkt);


int	usb_control_msg (USB_DEVICE_INFO usbDeviceInfo, BYTE bmRequestType, int request, int Value, int Index, char *data, int Length, int timeout);
void	RF_CallsignPrint (unsigned char header[]);

int		bufferPnt = 0;

void	read_from_rig_header(USB_DEVICE_INFO usbDeviceInfo) 	/* read from rig (DV packet) */
{
//	unsigned char buffer[41];
	int	ret;
	unsigned char ssn_temp[2];
	packet pkt;
	call_table call_pkt;

	/***  from RIG  ***/

    ret = usb_control_msg(usbDeviceInfo, 0xC0, GET_HEADER, 0, 0, pkt.body, 32, 100);
	ret = usb_control_msg(usbDeviceInfo, 0xC0, GET_HEADER, 0, 0, &pkt.body[32], 9, 100);

	RF_CallsignPrint (pkt.body);
	bufferPnt = 0;

	usb_control_msg(usbDeviceInfo, 0xC0, GET_SN_VALUE, 0, 0, ssn_temp, 2, 100);
	call_pkt.ssn = ssn_temp[0] * 4 + (ssn_temp[1] >> 6);


/* RF header send */
		send_dv_callEntry (call_pkt);
		pkt.dest_repeater_id = 0x20;
		pkt.send_repeater_id = 'N';
		pkt.send_terminal_id = 'E';;
		pkt.seq_high = 0;
		pkt.seq_low = 0;
		pkt.type_id = 0x10;
		send_dv_header (pkt);
		return;
}

void	RF_CallsignPrint (unsigned char header[])
{
	xLCDMessage xMessage;
	extern xQueueHandle xLCDQueue;
	int	i;

	for ( i = 0 ; i < 8 ; i++)
	{
		LCDText[i] = header[i+27];
		LCDText[i+8] = header[i+19];
		LCDText[i+16] = header[i+11];
		LCDText[i+24] = header[i+3];
	}
		xMessage.pcMessage = LCDText;
 		xMessage.xMinDisplayTime = 1000 / portTICK_RATE_MS;
		xQueueSend( xLCDQueue, &xMessage, 0 );
	return;
}

int	read_from_rig_voice(USB_DEVICE_INFO usbDeviceInfo) 	/* read from rig (DV packet) */
{
	packet pkt;
	unsigned char	buffer[12];
	int			ret, i;
	BYTE	status;
	char	lastframe1[3] ={0x55,0x55,0x55};
	char	lastframe2[3] ={0x55,0xc8,0x7a};


       		ret = usb_control_msg(usbDeviceInfo, 0xC0, GET_DATA, 0, 0, buffer, 12, 100);
			if (ret != 0)
			{
				for (i = 0 ; i < ret; i++)
				{
					pkt.body[bufferPnt] = buffer[i];
					bufferPnt++;
					if (bufferPnt == 12)
					{
						bufferPnt = 0;
						send_dv_packet (pkt);
					}
				}
			}

			if (ret == 0)
			{
	        	ret = usb_control_msg(usbDeviceInfo, 0xC0, GET_AD_STATUS, 0, 0, &status, 1, 100);
				if (!(status & COS_OnOff))
				{
					if (!strncmp (pkt.body,lastframe1,3))
					{
						if (!strncmp(pkt.body,lastframe2,3))
						{
							return 1;
						}
					}
					pkt.body[0] = 0x55;
					pkt.body[1] = 0x55;
					pkt.body[2] = 0x55;
					send_dv_packet (pkt);
					pkt.body[0] = 0x55;
					pkt.body[1] = 0xc8;
					pkt.body[2] = 0x7a;
					send_dv_packet (pkt);
					return 1;
				}
		}
		if (bufferPnt != 0)
		{
			send_dv_packet (pkt);
		}
	return 0;
}

void usb_send_header (packet pkt)
{	
	USB_DEVICE_INFO usbDeviceInfo;
	unsigned char buffer[12];

	/* Callsign set */
	usb_control_msg(usbDeviceInfo, 0x40, SET_MyCALL, 0, 0, &pkt.body[27], 8, 100);
	usb_control_msg(usbDeviceInfo, 0x40, SET_MyCALL2, 0, 0, &pkt.body[35], 4, 100);
	usb_control_msg(usbDeviceInfo, 0x40, SET_YourCALL, 0, 0, &pkt.body[19], 8, 100);
	usb_control_msg(usbDeviceInfo, 0x40, SET_RPT1CALL, 0, 0, &pkt.body[11], 8, 100);
	usb_control_msg(usbDeviceInfo, 0x40, SET_RPT2CALL, 0, 0, &pkt.body[3], 8, 100);
	usb_control_msg(usbDeviceInfo, 0x40, SET_FLAGS, 0, 0, &pkt.body[0], 3, 100);
	/* PTT ON */
	usb_control_msg(usbDeviceInfo, 0x40, SET_PTT, ON, 0, buffer, 0, 100);
}

void usb_send_voice (BYTE pkt[])
{
	USB_DEVICE_INFO usbDeviceInfo;

	usb_control_msg(usbDeviceInfo, 0x40, PUT_DATA, 0, 0, pkt, 12, 100);
}
