// ChannelScan.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>

// Formula for the frequencies to be scanned
#pragma pack(1)       // set byte packing

typedef struct {
	DWORD		Freq;
	UINT 		Channel;
} CANAL_INFO;

#pragma pack()       // set back the default packing

//channels sorted by frequencies
static CANAL_INFO m_FrequencyChannelInfo[99] = 
{
	{ 136000000,  32 }, //channel are separated 375000 Hz bw
	{ 136375000,  33 },
	{ 136750000,  34 },
	{ 137125000,  35 },
	{ 137500000,  36 },
	{ 137875000,  37 },
	{ 138250000,  38 },
	{ 138625000,  39 },
	{ 139000000,  40 },
	{ 139375000,  41 },
	{ 139750000,  42 },
	{ 140125000,  43 },
	{ 140500000,  44 },
	{ 140875000,  45 },
	{ 141250000,  46 },
	{ 141625000,  47 },
	{ 142000000,  48 },
	{ 142375000,  49 },
	{ 142750000,  50 },
	{ 143125000,  51 },
	{ 143500000,  52 },
	{ 143875000,  53 },
	{ 144250000,  54 },
	{ 144625000,  55 },
	{ 145000000,  56 },
	{ 145375000,  57 },
	{ 145750000,  58 },
	{ 146125000,  59 },
	{ 146500000,  60 },
	{ 146875000,  61 },
	{ 147250000,  62 },
	{ 147625000,  63 },
	{ 148000000,  64 },
	{ 148375000,  65 },
	{ 148750000,  66 },
	{ 149125000,  67 },
	{ 149500000,  68 },
	{ 149875000,  69 },
	{ 150250000,  70 },
	{ 150625000,  71 },
	{ 151000000,  72 },
	{ 151375000,  73 },
	{ 151750000,  74 },
	{ 152125000,  75 },
	{ 152500000,  76 },
	{ 152875000,  77 },
	{ 153250000,  78 },
	{ 153625000,  79 },
	{ 154000000,  80 },
	{ 154375000,  81 },
	{ 154750000,  82 },
	{ 155125000,  83 },
	{ 155500000,  84 },
	{ 155875000,  85 },
	{ 156250000,  86 },
	{ 156625000,  87 },
	{ 157000000,  88 },
	{ 157375000,  89 },
	{ 157750000,  90 },
	{ 158125000,  91 },
	{ 158500000,  92 },
	{ 158875000,  93 },
	{ 159250000,  94 },
	{ 159625000,  95 },
	{ 160000000,  96 },
	{ 160375000,  97 },
	{ 160750000,  98 },
	{ 161125000,  99 }, 
						//frequency step discontinuity - 1125000 Hz 
	{ 162250000,   1 }, //channel are separated 375000 Hz bw again
	{ 162625000,  17 },
	{ 163000000,   2 },
	{ 163375000,  18 },
	{ 163750000,  3 },
	{ 164125000,  19 },
	{ 164500000,  4 },
	{ 164875000,  20 },
	{ 165250000,  5 },
	{ 165625000,  21 },
	{ 166000000,  6 },
	{ 166375000,  22 },
	{ 166750000,  7 },
	{ 167125000,  23 },
	{ 167500000,  8 },
	{ 167875000,  24 },
	{ 168250000,  9 },
	{ 168625000,  25 },
	{ 169000000,  10 },
	{ 169375000,  26 },
	{ 169750000,  11 },
	{ 170125000,  27 },
	{ 170500000,  12 },
	{ 170875000,  28 },
	{ 171250000,  13 },
	{ 171625000,  29 },
	{ 172000000,  14 },
	{ 172375000,  30 },
	{ 172750000,  15 },
	{ 173125000,  31 },
	{ 173500000,  16 }
};

#define ScanFreq(i)		m_FrequencyChannelInfo[i].Freq
#define ScanFreqsNum	99

typedef int			RADIOHANDLE;
typedef void		(__stdcall* RADIOHANDLERCALLBACK)(void* pTarget, void* pBuffer, DWORD dwSize, DWORD dwSamplingRate);

// G33WSB API function type declarations
typedef int		(__stdcall *FNCOpenRadioDevice)(int iDeviceNum);
typedef BOOL	(__stdcall *FNCCloseRadioDevice)(RADIOHANDLE hRadio);
typedef BOOL	(__stdcall *FNCSetAtten)(RADIOHANDLE hRadio, BOOL fAtten);
typedef BOOL	(__stdcall *FNCSetPower)(RADIOHANDLE hRadio, BOOL fPower);
typedef BOOL	(__stdcall *FNCInitializeDemodulator)(RADIOHANDLE hRadio, char* pszCalFilePath);
typedef int		(__stdcall *FNCSetFreqPipelined)(RADIOHANDLE hRadio, DWORD dwFreq, BOOL IsFirst, LONG Settling);
typedef int		(__stdcall *FNCGetSSPipelined)(RADIOHANDLE hRadio, int *SS, BYTE *RawSS, int *RSSI, int *AGC);
typedef BOOL	(__stdcall *FNCSetupStreams)(RADIOHANDLE hRadio, RADIOHANDLERCALLBACK IFHandler, void* IFTarget, RADIOHANDLERCALLBACK AudioHandler, void* AudioTarget);
typedef DWORD	(__stdcall *FNCGetChannelFrequency)(int nChannel);

int main(int argc, char* argv[])
{
	// load the G3 API library
	HMODULE dll=LoadLibrary("wrg39wsbapi.dll");
	if (!dll) 
	{
		puts("WRG39WSB.DLL not found !"); 
		return 0;
	}

	// link G3 API functions
	FNCOpenRadioDevice			OpenRadioDevice			= (FNCOpenRadioDevice)GetProcAddress(dll,"OpenRadioDevice");
	FNCCloseRadioDevice			CloseRadioDevice		= (FNCCloseRadioDevice)GetProcAddress(dll,"CloseRadioDevice");
	FNCSetAtten					SetAtten				= (FNCSetAtten)GetProcAddress(dll,"SetAtten");
	FNCSetPower					SetPower				= (FNCSetPower)GetProcAddress(dll,"SetPower");
	FNCInitializeDemodulator	InitializeDemodulator	= (FNCInitializeDemodulator)GetProcAddress(dll,"InitializeDemodulator");
	FNCSetFreqPipelined			SetFreqPipelined		= (FNCSetFreqPipelined)GetProcAddress(dll,"SetFreqPipelined");
	FNCGetSSPipelined			GetSSPipelined			= (FNCGetSSPipelined)GetProcAddress(dll,"GetSSPipelined");
	FNCSetupStreams				SetupStreams			= (FNCSetupStreams)GetProcAddress(dll,"SetupStreams");
	FNCGetChannelFrequency		GetChannelFrequency		= (FNCGetChannelFrequency)GetProcAddress(dll,"GetChannelFrequency");
	
	// open the first available radio
	int hRadio = OpenRadioDevice(0);
	if (!hRadio) 
	{
		puts("No G39WSB device could be opened !");
		FreeLibrary(dll); 
		return 0;
	}

	// Initialize device and set Power, Attenuator
	if (InitializeDemodulator(hRadio, NULL)) 
		puts("The device is initialized");
	else 
		puts("The device failed to initialization");

	if (SetPower(hRadio,TRUE)) 
		puts("The device is turned ON");
	else 
		puts("The device failed to turn ON");

	if (SetAtten(hRadio,FALSE)) 
		puts("The attenuator is OFF");
	else 
		puts("The attenuator failed to turn OFF");

	DWORD dwFrequency = 0;
	for (int i = 1; i <= ScanFreqsNum; i++) 
	{
		dwFrequency = GetChannelFrequency(i);
		if(dwFrequency == 0)
			printf("Channel = % 2d - Frequency = %ld - Error while channel enumerating..\n", i, dwFrequency);
		else
			printf("Channel = % 2d - Frequency = %ld\n", i, dwFrequency);
	}

	puts("Press <Enter>");
	getchar();

	// let's start the pipelined scanning by passing the first frequency 
	if (SetFreqPipelined(hRadio, m_FrequencyChannelInfo[0].Freq, TRUE, 50)) 
	{
		puts("Error while pipelining the first frequency..");
	}
	else 
	{
		size_t	i;
		DWORD	dwFreq;
		UINT	uChannel;
		DWORD	dwFreqPrev		= m_FrequencyChannelInfo[0].Freq;
		UINT	uChannelPrev	= m_FrequencyChannelInfo[0].Channel;

		puts("First frequency successfully pipelined..");
		// now it does all steps that can be done in a continous loop
		for (i=1; i < ScanFreqsNum; i++) 
		{
			dwFreq = m_FrequencyChannelInfo[i].Freq;
			uChannel = m_FrequencyChannelInfo[i].Channel;

			// pipelines the next frequency
			if (SetFreqPipelined(hRadio, dwFreq, FALSE, 10)) 
				printf("Error while pipelining Channel [%u] - %ld..\n", uChannel, dwFreq);
			else 
			{
				int SS,RSSI,AGC,Res;
				BYTE RawSS;

				Res=GetSSPipelined(hRadio,&SS,&RawSS,&RSSI,&AGC);
				if (Res) 
					printf("Error while reading SS for Channel [%d] - %ld..\n", uChannelPrev, dwFreqPrev);
				else 
					printf("%ld - Channel=% 2u - SS=%d   RawSS=%u   AGC=%d   RSSI=%d\n", dwFreqPrev, uChannelPrev, SS,RawSS,AGC,RSSI);
			}

			dwFreqPrev = dwFreq;
			uChannelPrev = uChannel;
			Sleep(5);
		}

		// the first step requires a dummy frequency pipelining
		dwFreq = m_FrequencyChannelInfo[0].Freq;
		uChannel = m_FrequencyChannelInfo[0].Channel;
		
		if (SetFreqPipelined(hRadio, dwFreq, FALSE, 25)) 
			printf("Error while re-pipelining Channel [%u] - %ld..\n", uChannel, dwFreq);
		else 
		{
			int SS,RSSI,AGC,Res;
			BYTE RawSS;

			Res=GetSSPipelined(hRadio,&SS,&RawSS,&RSSI,&AGC);
			if (Res) 
				printf("Error while reading SS for Channel [%u] - %ld..\n", uChannel, dwFreq);
			else 
				printf("%ld - Channel=%u - SS=% 2d   RawSS=%u   AGC=%d   RSSI=%d\n", dwFreqPrev, uChannelPrev, SS, RawSS, AGC, RSSI);
		}
	}

	// close the device handle
	if (CloseRadioDevice(hRadio)) 
		puts("The device is closed properly");
	else 
		puts("The device failed to close");

	// free the G3 API library
	FreeLibrary(dll);

	puts("Press <Enter>");
	getchar();

	return 0;
}