#include <windows.h>
#include <winioctl.h>
#include "mcc_mcx.h"
#include "ack_w32.h"

static BOOL
AcksysProto(HANDLE chan, int prot, BOOL fullDuplex, int clock, int packetSize)
{
	MCX_SYNCHRONIZATION_PARAMETERS sp;
	DWORD count;

	//
	// passer en mode HDLC avec les horloges appropriees
	//
	sp.Version = 1;
	sp.Duplex = fullDuplex ? MCX_WAY_FULLDUPLEX : MCX_WAY_HALFDUPLEX;
	sp.SynchronousMode = prot;
	sp.MonosyncChar = 0x7e;
	sp.Options = 0;
	sp.DataLength = packetSize;
	switch(clock) {
	case ACK_NOCLOCK:
		sp.TransmitClockSource = MCX_CLOCK_BRG;
		sp.ReceiveClockSource = MCX_CLOCK_BRG;  
		sp.TxClockPinSource = MCX_CLOCK_TRXC_HIGH;
		break;
	case ACK_ETTD:
		sp.TransmitClockSource = MCX_CLOCK_TXCI;
		sp.ReceiveClockSource = MCX_CLOCK_RXC;  
		sp.TxClockPinSource = MCX_CLOCK_TRXC_HIGH;      // not used
		break;
	case ACK_ETCD:
		sp.TransmitClockSource = MCX_CLOCK_BRG;
		sp.ReceiveClockSource = MCX_CLOCK_BRG;  
		sp.TxClockPinSource = MCX_CLOCK_TXCLOCK;
		break;
	case ACK_NULLMODEM:
		sp.TransmitClockSource = MCX_CLOCK_BRG;
		sp.ReceiveClockSource = MCX_CLOCK_RXC;  
		sp.TxClockPinSource = MCX_CLOCK_BRG;
		break;
	default:
		return FALSE;
	}

	if(!AcksysIoControl(chan,IOCTL_SERIAL_SET_SYNC_STATE,
			&sp,sizeof(sp),NULL,0,&count)) {
		printf("SET_SYNC_STATE Ioctl: error %d\n",GetLastError());
		return FALSE;
	}
	return TRUE;
}

BOOL
AcksysAsync(HANDLE chan, BOOL fullDuplex, int clock, int packetSize)
{
	return AcksysProto(chan,MCX_SYNC_CHAR,fullDuplex,clock,packetSize);
}

BOOL
AcksysHdlc(HANDLE chan, BOOL fullDuplex, int clock, int packetSize)
{
	return AcksysProto(chan,MCX_SYNC_HDLC,fullDuplex,clock,packetSize);
}
