//
//  Code for Packet using ARDOP like frames.
//	
//	This Module handles frame level stuff, and can be used
//	with a KISS interface. Module pktSession inplements an
//	ax.25 like Level 2, with dynamic parameter updating
//
// This uses Special Variable Length frames

// Packet has header of 6 bytes  sent in 4FSK.500.100. 
// Header is 6 bits Type 10 Bits Len 2 bytes CRC 2 bytes RS
// Once we have that we receive the rest of the packet in the 
// mode defined in the header.
// Uses Frame Type 0xC0, symbolic name PktFrameHeader


#ifdef WIN32
#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#define _CRT_SECURE_NO_DEPRECATE

#include <windows.h>
#include <winioctl.h>
#else
#define HANDLE int
#endif

#include "ARDOPC.h"


extern UCHAR KISSBUFFER[500]; // Long enough for stuffed KISS frame
extern int KISSLength;


VOID EncodePacket(UCHAR * Data, int Len);
VOID AddTxByteDirect(UCHAR Byte);
VOID AddTxByteStuffed(UCHAR Byte);
unsigned short int compute_crc(unsigned char *buf,int len);
void PacketStartTX();
BOOL GetNextKISSFrame();
VOID SendAckModeAck();

extern unsigned char bytEncodedBytes[4500];		// I think the biggest is 600 bd 768 + overhead
extern int EncLen;

extern UCHAR PacketMon[360];
extern int PacketMonMore;
extern int PacketMonLength;

#define ARDOPBufferSize 12000 * 100

short ARDOPTXBuffer[4][12000 * 100];		// Enough to hold whole frame of samples

int ARDOPTXLen[4] = { 0,0,0,0 };			// Length of frame
int ARDOPTXPtr[4] = { 0,0,0,0 };			// Tx Pointer

int pktBandwidth = 4;
int pktMaxBandwidth = 8;
int pktMaxFrame = 4;
int pktPacLen = 80;

int pktMode = 0;
int pktRXMode;		// Currently receiving mode

int pktDataLen;
int pktRSLen;

// Now use Mode number to encode type and bandwidth

const char pktMod[16][12] = {
	"4PSK/200",
	"4FSK/500", "4PSK/500", "8PSK/500", "16QAM/500",
	"4FSK/1000", "4PSK/1000", "8PSK/1000", "16QAM/1000",
	"4FSK/2000", "4PSK/2000", "8PSK/2000", "16QAM/2000",
};

// Note FSK modes, though identified as 200 500 or 1000 actually
// occupy 500, 1000 or 2000 BW

const int pktBW[16] = {200,
					500, 500, 500, 500,
					1000, 1000, 1000, 1000,
					2000, 2500, 2500, 2500};

const int pktCarriers[16] = {
					1,
					1, 2, 2, 2,
					2, 4, 4, 4,
					4, 10, 10, 10};

const BOOL pktFSK[16] = {0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0};

int pktModeLen = 13;

VOID PktARDOPEncode(UCHAR * Data, int Len, int Chan)
{
	unsigned char DataToSend[4];
	int pktNumCar = pktCarriers[pktMode];

	// Header now sent as 4FSK.500.100
	// 6 Bits Mode, 10 Bits Length

	// 2 Bytes Header 2 Bytes CRC 2 Bytes RS

	if (Len > 1023)
		return;

	DataToSend[0] = (pktMode << 2)|(Len >> 8);
	DataToSend[1] = Len & 0xff;
	
	// Calc Data and RS Length

	pktDataLen = (Len + (pktNumCar - 1))/pktNumCar; // Round up

	pktRSLen = pktDataLen >> 2;			// Try 25% for now

	if (pktRSLen & 1)
		pktRSLen++;						// Odd RS bytes no use

	if (pktRSLen < 4)
		pktRSLen = 4;					// At least 4

	// Encode Header
	
	EncLen = EncodeFSKData(PktFrameHeader, DataToSend, 2, bytEncodedBytes);
	
	// Encode Data

	if (pktFSK[pktMode])
		EncodeFSKData(PktFrameData, Data, Len, &bytEncodedBytes[EncLen]);
	else
		EncodePSKData(PktFrameData, Data, Len, &bytEncodedBytes[EncLen]);

	// Header is FSK
	
	Mod4FSKDataAndPlay(bytEncodedBytes, EncLen, intCalcLeader, Chan);  // Modulate Data frame 
}

// Called when link idle to see if any packet frames to send

void PktARDOPStartTX()
{
/*
if (GetNextKISSFrame() == FALSE)
		return;			// nothing to send
	
	while (TRUE)				// loop till we run out of packets
	{
		switch(KISSBUFFER[0])
		{
		case 0:			// Normal Data

			WriteDebugLog(LOGALERT, "Sending Packet Frame Len %d", KISSLength - 1); 

			PktARDOPEncode(KISSBUFFER + 1, KISSLength - 1);

			// Trace it

			if (PacketMonLength == 0)	// Ingore if one queued
			{
				PacketMon[0] = 0x80;		// TX Flag
				memcpy(&PacketMon[1], &KISSBUFFER[1], KISSLength);
	
				PacketMonLength = KISSLength;
			}

			break;

		case 6:			// HW Paramters. Set Mode and Bandwidth

			pktMode = KISSBUFFER[1]; 
			break;
		
		case 12:
		
		// Ackmode frame. Return ACK Bytes (first 2) to host when TX complete
		
			WriteDebugLog(LOGALERT, "Sending Packet Frame Len %d", KISSLength - 3); 
			PktARDOPEncode(KISSBUFFER + 3, KISSLength - 3);

			// Returns when Complete so can send ACK

			SendAckModeAck();
			break;
		}

		// See if any more

		if (GetNextKISSFrame() == FALSE)
			break;			// no more to send
	}
*/
}

VOID SendAckModeAck()
{

}