mirror of
				https://github.com/ShaYmez/P25Clients.git
				synced 2025-11-03 20:50:22 -05:00 
			
		
		
		
	Initial commit.
This commit is contained in:
		
						commit
						47cce73dfb
					
				
							
								
								
									
										16
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
Debug
 | 
			
		||||
Release
 | 
			
		||||
x64
 | 
			
		||||
MMDVMHost
 | 
			
		||||
*.o
 | 
			
		||||
*.opendb
 | 
			
		||||
*.bak
 | 
			
		||||
*.obj
 | 
			
		||||
*~
 | 
			
		||||
*.sdf
 | 
			
		||||
*.log
 | 
			
		||||
*.zip
 | 
			
		||||
*.exe
 | 
			
		||||
*.user
 | 
			
		||||
*.VC.db
 | 
			
		||||
.vs
 | 
			
		||||
							
								
								
									
										28
									
								
								P25Clients.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								P25Clients.sln
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
 | 
			
		||||
Microsoft Visual Studio Solution File, Format Version 12.00
 | 
			
		||||
# Visual Studio 14
 | 
			
		||||
VisualStudioVersion = 14.0.25420.1
 | 
			
		||||
MinimumVisualStudioVersion = 10.0.40219.1
 | 
			
		||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "P25Parrot", "P25Parrot\P25Parrot.vcxproj", "{2AE94EAA-FD57-45C9-8555-6425CFA777A3}"
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
		Debug|x64 = Debug|x64
 | 
			
		||||
		Debug|x86 = Debug|x86
 | 
			
		||||
		Release|x64 = Release|x64
 | 
			
		||||
		Release|x86 = Release|x86
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 | 
			
		||||
		{2AE94EAA-FD57-45C9-8555-6425CFA777A3}.Debug|x64.ActiveCfg = Debug|x64
 | 
			
		||||
		{2AE94EAA-FD57-45C9-8555-6425CFA777A3}.Debug|x64.Build.0 = Debug|x64
 | 
			
		||||
		{2AE94EAA-FD57-45C9-8555-6425CFA777A3}.Debug|x86.ActiveCfg = Debug|Win32
 | 
			
		||||
		{2AE94EAA-FD57-45C9-8555-6425CFA777A3}.Debug|x86.Build.0 = Debug|Win32
 | 
			
		||||
		{2AE94EAA-FD57-45C9-8555-6425CFA777A3}.Release|x64.ActiveCfg = Release|x64
 | 
			
		||||
		{2AE94EAA-FD57-45C9-8555-6425CFA777A3}.Release|x64.Build.0 = Release|x64
 | 
			
		||||
		{2AE94EAA-FD57-45C9-8555-6425CFA777A3}.Release|x86.ActiveCfg = Release|Win32
 | 
			
		||||
		{2AE94EAA-FD57-45C9-8555-6425CFA777A3}.Release|x86.Build.0 = Release|Win32
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
EndGlobal
 | 
			
		||||
							
								
								
									
										18
									
								
								P25Parrot/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								P25Parrot/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
CC      = gcc
 | 
			
		||||
CXX     = g++
 | 
			
		||||
CFLAGS  = -g -O3 -Wall -std=c++0x
 | 
			
		||||
LIBS    =
 | 
			
		||||
LDFLAGS = -g
 | 
			
		||||
 | 
			
		||||
OBJECTS = Network.o P25Parrot.o Parrot.o StopWatch.o Timer.o UDPSocket.o Utils.o
 | 
			
		||||
 | 
			
		||||
all:		P25Parrot
 | 
			
		||||
 | 
			
		||||
P25Parrot:	$(OBJECTS)
 | 
			
		||||
		$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o P25Parrot
 | 
			
		||||
 | 
			
		||||
%.o: %.cpp
 | 
			
		||||
		$(CXX) $(CFLAGS) -c -o $@ $<
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
		$(RM) P25Parrot *.o *.d *.bak *~
 | 
			
		||||
							
								
								
									
										18
									
								
								P25Parrot/Makefile.Solaris
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								P25Parrot/Makefile.Solaris
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
CC      = gcc
 | 
			
		||||
CXX     = g++
 | 
			
		||||
CFLAGS  = -g -O3 -Wall -std=c++0x
 | 
			
		||||
LIBS    = -lsocket
 | 
			
		||||
LDFLAGS = -g
 | 
			
		||||
 | 
			
		||||
OBJECTS = Network.o P25Parrot.o Parrot.o StopWatch.o Timer.o UDPSocket.o Utils.o
 | 
			
		||||
 | 
			
		||||
all:		P25Parrot
 | 
			
		||||
 | 
			
		||||
P25Parrot:	$(OBJECTS)
 | 
			
		||||
		$(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o P25Parrot
 | 
			
		||||
 | 
			
		||||
%.o: %.cpp
 | 
			
		||||
		$(CXX) $(CFLAGS) -c -o $@ $<
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
		$(RM) P25Parrot *.o *.d *.bak *~
 | 
			
		||||
							
								
								
									
										108
									
								
								P25Parrot/Network.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								P25Parrot/Network.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,108 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2009-2014,2016 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "Network.h"
 | 
			
		||||
#include "Utils.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
const unsigned int BUFFER_LENGTH = 200U;
 | 
			
		||||
 | 
			
		||||
CNetwork::CNetwork(unsigned int port, bool debug) :
 | 
			
		||||
m_socket(port),
 | 
			
		||||
m_address(),
 | 
			
		||||
m_port(0U),
 | 
			
		||||
m_debug(debug),
 | 
			
		||||
m_buffer(1000U, "P25 Network")
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CNetwork::~CNetwork()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CNetwork::open()
 | 
			
		||||
{
 | 
			
		||||
	::fprintf(stdout, "Opening P25 network connection\n");
 | 
			
		||||
 | 
			
		||||
	return m_socket.open();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CNetwork::write(const unsigned char* data, unsigned int length)
 | 
			
		||||
{
 | 
			
		||||
	if (m_port == 0U)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	assert(data != NULL);
 | 
			
		||||
 | 
			
		||||
	if (m_debug)
 | 
			
		||||
		CUtils::dump(1U, "P25 Network Data Sent", data, length);
 | 
			
		||||
 | 
			
		||||
	return m_socket.write(data, length, m_address, m_port);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CNetwork::clock(unsigned int ms)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char buffer[BUFFER_LENGTH];
 | 
			
		||||
 | 
			
		||||
	in_addr address;
 | 
			
		||||
	unsigned int port;
 | 
			
		||||
	int length = m_socket.read(buffer, BUFFER_LENGTH, address, port);
 | 
			
		||||
	if (length <= 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	m_address.s_addr = address.s_addr;
 | 
			
		||||
	m_port = port;
 | 
			
		||||
 | 
			
		||||
	if (m_debug)
 | 
			
		||||
		CUtils::dump(1U, "P25 Network Data Received", buffer, length);
 | 
			
		||||
 | 
			
		||||
	unsigned char l = length;
 | 
			
		||||
	m_buffer.addData(&l, 1U);
 | 
			
		||||
 | 
			
		||||
	m_buffer.addData(buffer, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int CNetwork::read(unsigned char* data)
 | 
			
		||||
{
 | 
			
		||||
	assert(data != NULL);
 | 
			
		||||
 | 
			
		||||
	if (m_buffer.isEmpty())
 | 
			
		||||
		return 0U;
 | 
			
		||||
 | 
			
		||||
	unsigned char len = 0U;
 | 
			
		||||
	m_buffer.getData(&len, 1U);
 | 
			
		||||
 | 
			
		||||
	m_buffer.getData(data, len);
 | 
			
		||||
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CNetwork::end()
 | 
			
		||||
{
 | 
			
		||||
	m_port = 0U;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CNetwork::close()
 | 
			
		||||
{
 | 
			
		||||
	m_socket.close();
 | 
			
		||||
 | 
			
		||||
	::fprintf(stdout, "Closing P25 network connection\n");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								P25Parrot/Network.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								P25Parrot/Network.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2009-2014,2016 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef	Network_H
 | 
			
		||||
#define	Network_H
 | 
			
		||||
 | 
			
		||||
#include "RingBuffer.h"
 | 
			
		||||
#include "UDPSocket.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
class CNetwork {
 | 
			
		||||
public:
 | 
			
		||||
	CNetwork(unsigned int port, bool debug);
 | 
			
		||||
	~CNetwork();
 | 
			
		||||
 | 
			
		||||
	bool open();
 | 
			
		||||
 | 
			
		||||
	bool write(const unsigned char* data, unsigned int length);
 | 
			
		||||
 | 
			
		||||
	unsigned int read(unsigned char* data);
 | 
			
		||||
 | 
			
		||||
	void end();
 | 
			
		||||
 | 
			
		||||
	void close();
 | 
			
		||||
 | 
			
		||||
	void clock(unsigned int ms);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	CUDPSocket   m_socket;
 | 
			
		||||
	in_addr      m_address;
 | 
			
		||||
	unsigned int m_port;
 | 
			
		||||
	bool         m_debug;
 | 
			
		||||
	CRingBuffer<unsigned char> m_buffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										142
									
								
								P25Parrot/P25Parrot.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								P25Parrot/P25Parrot.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,142 @@
 | 
			
		||||
/*
 | 
			
		||||
*   Copyright (C) 2016 by Jonathan Naylor G4KLX
 | 
			
		||||
*
 | 
			
		||||
*   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
*   it under the terms of the GNU General Public License as published by
 | 
			
		||||
*   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
*   (at your option) any later version.
 | 
			
		||||
*
 | 
			
		||||
*   This program is distributed in the hope that it will be useful,
 | 
			
		||||
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
*   GNU General Public License for more details.
 | 
			
		||||
*
 | 
			
		||||
*   You should have received a copy of the GNU General Public License
 | 
			
		||||
*   along with this program; if not, write to the Free Software
 | 
			
		||||
*   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "StopWatch.h"
 | 
			
		||||
#include "P25Parrot.h"
 | 
			
		||||
#include "Parrot.h"
 | 
			
		||||
#include "Network.h"
 | 
			
		||||
#include "Version.h"
 | 
			
		||||
#include "Timer.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv)
 | 
			
		||||
{
 | 
			
		||||
	if (argc == 1) {
 | 
			
		||||
		::fprintf(stderr, "Usage: P25Parrot <port>\n");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unsigned int port = ::atoi(argv[1]);
 | 
			
		||||
	if (port == 0U) {
 | 
			
		||||
		::fprintf(stderr, "P25Parrot: invalid port number\n");
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CP25Parrot parrot(port);
 | 
			
		||||
	parrot.run();
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CP25Parrot::CP25Parrot(unsigned int port) :
 | 
			
		||||
m_port(port)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CP25Parrot::~CP25Parrot()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CP25Parrot::run()
 | 
			
		||||
{
 | 
			
		||||
	CParrot parrot(180U);
 | 
			
		||||
	CNetwork network(m_port, false);
 | 
			
		||||
 | 
			
		||||
	bool ret = network.open();
 | 
			
		||||
	if (!ret)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	CStopWatch stopWatch;
 | 
			
		||||
	stopWatch.start();
 | 
			
		||||
 | 
			
		||||
	CTimer watchdogTimer(1000U, 0U, 1500U);
 | 
			
		||||
	CTimer turnaroundTimer(1000U, 2U);
 | 
			
		||||
 | 
			
		||||
	CStopWatch playoutTimer;
 | 
			
		||||
	unsigned int count = 0U;
 | 
			
		||||
	bool playing = false;
 | 
			
		||||
 | 
			
		||||
	::fprintf(stdout, "Starting P25Parrot-%s\n", VERSION);
 | 
			
		||||
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		unsigned char buffer[200U];
 | 
			
		||||
 | 
			
		||||
		unsigned int len = network.read(buffer);
 | 
			
		||||
		if (len > 0U) {
 | 
			
		||||
			parrot.write(buffer, len);
 | 
			
		||||
			watchdogTimer.start();
 | 
			
		||||
 | 
			
		||||
			if ((buffer[0U] == 0x6AU && buffer[15U] == 0x00U) || (buffer[0U] == 0x73U && buffer[15U] == 0x00U)) {
 | 
			
		||||
				::fprintf(stdout, "Received end of transmission\n");
 | 
			
		||||
				turnaroundTimer.start();
 | 
			
		||||
				watchdogTimer.stop();
 | 
			
		||||
				parrot.end();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (turnaroundTimer.isRunning() && turnaroundTimer.hasExpired()) {
 | 
			
		||||
			if (!playing) {
 | 
			
		||||
				playoutTimer.start();
 | 
			
		||||
				playing = true;
 | 
			
		||||
				count = 0U;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// A frame every 20ms
 | 
			
		||||
			unsigned int wanted = playoutTimer.elapsed() / 20U;
 | 
			
		||||
			while (count < wanted) {
 | 
			
		||||
				len = parrot.read(buffer);
 | 
			
		||||
				if (len > 0U) {
 | 
			
		||||
					network.write(buffer, len);
 | 
			
		||||
					count++;
 | 
			
		||||
				} else {
 | 
			
		||||
					parrot.clear();
 | 
			
		||||
					network.end();
 | 
			
		||||
					turnaroundTimer.stop();
 | 
			
		||||
					playing = false;
 | 
			
		||||
					count = wanted;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		unsigned int ms = stopWatch.elapsed();
 | 
			
		||||
		stopWatch.start();
 | 
			
		||||
 | 
			
		||||
		network.clock(ms);
 | 
			
		||||
		watchdogTimer.clock(ms);
 | 
			
		||||
		turnaroundTimer.clock(ms);
 | 
			
		||||
 | 
			
		||||
		if (watchdogTimer.isRunning() && watchdogTimer.hasExpired()) {
 | 
			
		||||
			::fprintf(stdout, "Network watchdog has expired\n");
 | 
			
		||||
			turnaroundTimer.start();
 | 
			
		||||
			watchdogTimer.stop();
 | 
			
		||||
			parrot.end();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (ms < 5U) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
			::Sleep(5UL);		// 5ms
 | 
			
		||||
#else
 | 
			
		||||
			::usleep(5000);		// 5ms
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	network.close();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								P25Parrot/P25Parrot.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								P25Parrot/P25Parrot.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
/*
 | 
			
		||||
*   Copyright (C) 2016 by Jonathan Naylor G4KLX
 | 
			
		||||
*
 | 
			
		||||
*   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
*   it under the terms of the GNU General Public License as published by
 | 
			
		||||
*   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
*   (at your option) any later version.
 | 
			
		||||
*
 | 
			
		||||
*   This program is distributed in the hope that it will be useful,
 | 
			
		||||
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
*   GNU General Public License for more details.
 | 
			
		||||
*
 | 
			
		||||
*   You should have received a copy of the GNU General Public License
 | 
			
		||||
*   along with this program; if not, write to the Free Software
 | 
			
		||||
*   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#if !defined(P25Parrot_H)
 | 
			
		||||
#define	P25Parrot_H
 | 
			
		||||
 | 
			
		||||
class CP25Parrot
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	CP25Parrot(unsigned int port);
 | 
			
		||||
	~CP25Parrot();
 | 
			
		||||
 | 
			
		||||
	void run();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	unsigned int m_port;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										171
									
								
								P25Parrot/P25Parrot.vcxproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								P25Parrot/P25Parrot.vcxproj
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,171 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <ItemGroup Label="ProjectConfigurations">
 | 
			
		||||
    <ProjectConfiguration Include="Debug|Win32">
 | 
			
		||||
      <Configuration>Debug</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Release|Win32">
 | 
			
		||||
      <Configuration>Release</Configuration>
 | 
			
		||||
      <Platform>Win32</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Debug|x64">
 | 
			
		||||
      <Configuration>Debug</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
    <ProjectConfiguration Include="Release|x64">
 | 
			
		||||
      <Configuration>Release</Configuration>
 | 
			
		||||
      <Platform>x64</Platform>
 | 
			
		||||
    </ProjectConfiguration>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <PropertyGroup Label="Globals">
 | 
			
		||||
    <ProjectGuid>{2AE94EAA-FD57-45C9-8555-6425CFA777A3}</ProjectGuid>
 | 
			
		||||
    <Keyword>Win32Proj</Keyword>
 | 
			
		||||
    <RootNamespace>P25Parrot</RootNamespace>
 | 
			
		||||
    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Application</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v140</PlatformToolset>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Application</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>false</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v140</PlatformToolset>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Application</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>true</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v140</PlatformToolset>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
 | 
			
		||||
    <ConfigurationType>Application</ConfigurationType>
 | 
			
		||||
    <UseDebugLibraries>false</UseDebugLibraries>
 | 
			
		||||
    <PlatformToolset>v140</PlatformToolset>
 | 
			
		||||
    <WholeProgramOptimization>true</WholeProgramOptimization>
 | 
			
		||||
    <CharacterSet>Unicode</CharacterSet>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
 | 
			
		||||
  <ImportGroup Label="ExtensionSettings">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Label="Shared">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
 | 
			
		||||
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
  <PropertyGroup Label="UserMacros" />
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
 | 
			
		||||
    <LinkIncremental>true</LinkIncremental>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
 | 
			
		||||
    <LinkIncremental>true</LinkIncremental>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
 | 
			
		||||
    <LinkIncremental>false</LinkIncremental>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
 | 
			
		||||
    <LinkIncremental>false</LinkIncremental>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <Optimization>Disabled</Optimization>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <SubSystem>Console</SubSystem>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
			
		||||
    </Link>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <Optimization>Disabled</Optimization>
 | 
			
		||||
      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <SubSystem>Console</SubSystem>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
			
		||||
    </Link>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <Optimization>MaxSpeed</Optimization>
 | 
			
		||||
      <FunctionLevelLinking>true</FunctionLevelLinking>
 | 
			
		||||
      <IntrinsicFunctions>true</IntrinsicFunctions>
 | 
			
		||||
      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <SubSystem>Console</SubSystem>
 | 
			
		||||
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 | 
			
		||||
      <OptimizeReferences>true</OptimizeReferences>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
			
		||||
    </Link>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <WarningLevel>Level3</WarningLevel>
 | 
			
		||||
      <PrecompiledHeader>
 | 
			
		||||
      </PrecompiledHeader>
 | 
			
		||||
      <Optimization>MaxSpeed</Optimization>
 | 
			
		||||
      <FunctionLevelLinking>true</FunctionLevelLinking>
 | 
			
		||||
      <IntrinsicFunctions>true</IntrinsicFunctions>
 | 
			
		||||
      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <Link>
 | 
			
		||||
      <SubSystem>Console</SubSystem>
 | 
			
		||||
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
 | 
			
		||||
      <OptimizeReferences>true</OptimizeReferences>
 | 
			
		||||
      <GenerateDebugInformation>true</GenerateDebugInformation>
 | 
			
		||||
      <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
 | 
			
		||||
    </Link>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClInclude Include="Network.h" />
 | 
			
		||||
    <ClInclude Include="P25Parrot.h" />
 | 
			
		||||
    <ClInclude Include="Parrot.h" />
 | 
			
		||||
    <ClInclude Include="RingBuffer.h" />
 | 
			
		||||
    <ClInclude Include="StopWatch.h" />
 | 
			
		||||
    <ClInclude Include="Timer.h" />
 | 
			
		||||
    <ClInclude Include="UDPSocket.h" />
 | 
			
		||||
    <ClInclude Include="Utils.h" />
 | 
			
		||||
    <ClInclude Include="Version.h" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClCompile Include="Network.cpp" />
 | 
			
		||||
    <ClCompile Include="P25Parrot.cpp" />
 | 
			
		||||
    <ClCompile Include="Parrot.cpp" />
 | 
			
		||||
    <ClCompile Include="StopWatch.cpp" />
 | 
			
		||||
    <ClCompile Include="Timer.cpp" />
 | 
			
		||||
    <ClCompile Include="UDPSocket.cpp" />
 | 
			
		||||
    <ClCompile Include="Utils.cpp" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
 | 
			
		||||
  <ImportGroup Label="ExtensionTargets">
 | 
			
		||||
  </ImportGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										65
									
								
								P25Parrot/P25Parrot.vcxproj.filters
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								P25Parrot/P25Parrot.vcxproj.filters
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,65 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Filter Include="Source Files">
 | 
			
		||||
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
 | 
			
		||||
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
 | 
			
		||||
    </Filter>
 | 
			
		||||
    <Filter Include="Header Files">
 | 
			
		||||
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
 | 
			
		||||
      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
 | 
			
		||||
    </Filter>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClInclude Include="Network.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="P25Parrot.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="Parrot.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="RingBuffer.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="StopWatch.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="Timer.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="UDPSocket.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="Utils.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
    <ClInclude Include="Version.h">
 | 
			
		||||
      <Filter>Header Files</Filter>
 | 
			
		||||
    </ClInclude>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ClCompile Include="Network.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="P25Parrot.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="Parrot.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="StopWatch.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="Timer.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="UDPSocket.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
    <ClCompile Include="Utils.cpp">
 | 
			
		||||
      <Filter>Source Files</Filter>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										81
									
								
								P25Parrot/Parrot.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								P25Parrot/Parrot.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,81 @@
 | 
			
		||||
/*
 | 
			
		||||
*   Copyright (C) 2016 by Jonathan Naylor G4KLX
 | 
			
		||||
*
 | 
			
		||||
*   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
*   it under the terms of the GNU General Public License as published by
 | 
			
		||||
*   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
*   (at your option) any later version.
 | 
			
		||||
*
 | 
			
		||||
*   This program is distributed in the hope that it will be useful,
 | 
			
		||||
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
*   GNU General Public License for more details.
 | 
			
		||||
*
 | 
			
		||||
*   You should have received a copy of the GNU General Public License
 | 
			
		||||
*   along with this program; if not, write to the Free Software
 | 
			
		||||
*   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "Parrot.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
CParrot::CParrot(unsigned int timeout) :
 | 
			
		||||
m_data(NULL),
 | 
			
		||||
m_length(timeout * 1550U + 1000U),
 | 
			
		||||
m_used(0U),
 | 
			
		||||
m_ptr(0U)
 | 
			
		||||
{
 | 
			
		||||
	assert(timeout > 0U);
 | 
			
		||||
 | 
			
		||||
	m_data = new unsigned char[m_length];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CParrot::~CParrot()
 | 
			
		||||
{
 | 
			
		||||
	delete[] m_data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CParrot::write(const unsigned char* data, unsigned int length)
 | 
			
		||||
{
 | 
			
		||||
	assert(data != NULL);
 | 
			
		||||
 | 
			
		||||
	if ((m_length - m_used) < (length + 2U))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	m_data[m_used] = length;
 | 
			
		||||
	::memcpy(m_data + m_used + 1U, data, length);
 | 
			
		||||
	m_used += length + 1U;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CParrot::end()
 | 
			
		||||
{
 | 
			
		||||
	m_ptr = 0U;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CParrot::clear()
 | 
			
		||||
{
 | 
			
		||||
	m_used = 0U;
 | 
			
		||||
	m_ptr = 0U;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int CParrot::read(unsigned char* data)
 | 
			
		||||
{
 | 
			
		||||
	assert(data != NULL);
 | 
			
		||||
 | 
			
		||||
	if (m_used == 0U)
 | 
			
		||||
		return 0U;
 | 
			
		||||
 | 
			
		||||
	unsigned int length = m_data[m_ptr];
 | 
			
		||||
	::memcpy(data, m_data + m_ptr + 1U, length);
 | 
			
		||||
	m_ptr += length + 1U;
 | 
			
		||||
 | 
			
		||||
	if (m_ptr >= m_used)
 | 
			
		||||
		m_used = 0U;
 | 
			
		||||
 | 
			
		||||
	return length;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								P25Parrot/Parrot.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								P25Parrot/Parrot.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
/*
 | 
			
		||||
*   Copyright (C) 2016 by Jonathan Naylor G4KLX
 | 
			
		||||
*
 | 
			
		||||
*   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
*   it under the terms of the GNU General Public License as published by
 | 
			
		||||
*   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
*   (at your option) any later version.
 | 
			
		||||
*
 | 
			
		||||
*   This program is distributed in the hope that it will be useful,
 | 
			
		||||
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
*   GNU General Public License for more details.
 | 
			
		||||
*
 | 
			
		||||
*   You should have received a copy of the GNU General Public License
 | 
			
		||||
*   along with this program; if not, write to the Free Software
 | 
			
		||||
*   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#if !defined(Parrot_H)
 | 
			
		||||
#define	Parrot_H
 | 
			
		||||
 | 
			
		||||
class CParrot
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	CParrot(unsigned int timeout);
 | 
			
		||||
	~CParrot();
 | 
			
		||||
 | 
			
		||||
	bool write(const unsigned char* data, unsigned int length);
 | 
			
		||||
 | 
			
		||||
	unsigned int read(unsigned char* data);
 | 
			
		||||
 | 
			
		||||
	void end();
 | 
			
		||||
 | 
			
		||||
	void clear();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	unsigned char* m_data;
 | 
			
		||||
	unsigned int   m_length;
 | 
			
		||||
	unsigned int   m_used;
 | 
			
		||||
	unsigned int   m_ptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										147
									
								
								P25Parrot/RingBuffer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								P25Parrot/RingBuffer.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,147 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2006-2009,2012,2013,2015,2016 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef RingBuffer_H
 | 
			
		||||
#define RingBuffer_H
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
template<class T> class CRingBuffer {
 | 
			
		||||
public:
 | 
			
		||||
	CRingBuffer(unsigned int length, const char* name) :
 | 
			
		||||
	m_length(length),
 | 
			
		||||
	m_name(name),
 | 
			
		||||
	m_buffer(NULL),
 | 
			
		||||
	m_iPtr(0U),
 | 
			
		||||
	m_oPtr(0U)
 | 
			
		||||
	{
 | 
			
		||||
		assert(length > 0U);
 | 
			
		||||
		assert(name != NULL);
 | 
			
		||||
 | 
			
		||||
		m_buffer = new T[length];
 | 
			
		||||
 | 
			
		||||
		::memset(m_buffer, 0x00, m_length * sizeof(T));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~CRingBuffer()
 | 
			
		||||
	{
 | 
			
		||||
		delete[] m_buffer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool addData(const T* buffer, unsigned int nSamples)
 | 
			
		||||
	{
 | 
			
		||||
		if (nSamples >= freeSpace()) {
 | 
			
		||||
			::fprintf(stderr, "**** Overflow in %s ring buffer, %u >= %u\n", m_name, nSamples, freeSpace());
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (unsigned int i = 0U; i < nSamples; i++) {
 | 
			
		||||
			m_buffer[m_iPtr++] = buffer[i];
 | 
			
		||||
 | 
			
		||||
			if (m_iPtr == m_length)
 | 
			
		||||
				m_iPtr = 0U;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool getData(T* buffer, unsigned int nSamples)
 | 
			
		||||
	{
 | 
			
		||||
		if (dataSize() < nSamples) {
 | 
			
		||||
			::fprintf(stderr, "**** Underflow in %s ring buffer, %u < %u\n", m_name, dataSize(), nSamples);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (unsigned int i = 0U; i < nSamples; i++) {
 | 
			
		||||
			buffer[i] = m_buffer[m_oPtr++];
 | 
			
		||||
 | 
			
		||||
			if (m_oPtr == m_length)
 | 
			
		||||
				m_oPtr = 0U;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool peek(T* buffer, unsigned int nSamples)
 | 
			
		||||
	{
 | 
			
		||||
		if (dataSize() < nSamples) {
 | 
			
		||||
			::fprintf(stderr, "**** Underflow peek in %s ring buffer, %u < %u\n", m_name, dataSize(), nSamples);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		unsigned int ptr = m_oPtr;
 | 
			
		||||
		for (unsigned int i = 0U; i < nSamples; i++) {
 | 
			
		||||
			buffer[i] = m_buffer[ptr++];
 | 
			
		||||
 | 
			
		||||
			if (ptr == m_length)
 | 
			
		||||
				ptr = 0U;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void clear()
 | 
			
		||||
	{
 | 
			
		||||
		m_iPtr = 0U;
 | 
			
		||||
		m_oPtr = 0U;
 | 
			
		||||
 | 
			
		||||
		::memset(m_buffer, 0x00, m_length * sizeof(T));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unsigned int freeSpace() const
 | 
			
		||||
	{
 | 
			
		||||
		if (m_oPtr == m_iPtr)
 | 
			
		||||
			return m_length;
 | 
			
		||||
 | 
			
		||||
		if (m_oPtr > m_iPtr)
 | 
			
		||||
			return m_oPtr - m_iPtr;
 | 
			
		||||
 | 
			
		||||
		return (m_length + m_oPtr) - m_iPtr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unsigned int dataSize() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_length - freeSpace();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool hasSpace(unsigned int length) const
 | 
			
		||||
	{
 | 
			
		||||
		return freeSpace() > length;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool hasData() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_oPtr != m_iPtr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool isEmpty() const
 | 
			
		||||
	{
 | 
			
		||||
		return m_oPtr == m_iPtr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	unsigned int m_length;
 | 
			
		||||
	const char*  m_name;
 | 
			
		||||
	T*           m_buffer;
 | 
			
		||||
	unsigned int m_iPtr;
 | 
			
		||||
	unsigned int m_oPtr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										84
									
								
								P25Parrot/StopWatch.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								P25Parrot/StopWatch.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "StopWatch.h"
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
 | 
			
		||||
CStopWatch::CStopWatch() :
 | 
			
		||||
m_frequency(),
 | 
			
		||||
m_start()
 | 
			
		||||
{
 | 
			
		||||
	::QueryPerformanceFrequency(&m_frequency);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CStopWatch::~CStopWatch()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned long CStopWatch::start()
 | 
			
		||||
{
 | 
			
		||||
	::QueryPerformanceCounter(&m_start);
 | 
			
		||||
 | 
			
		||||
	return (unsigned long)(m_start.QuadPart / m_frequency.QuadPart);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int CStopWatch::elapsed()
 | 
			
		||||
{
 | 
			
		||||
	LARGE_INTEGER now;
 | 
			
		||||
	::QueryPerformanceCounter(&now);
 | 
			
		||||
 | 
			
		||||
	LARGE_INTEGER temp;
 | 
			
		||||
	temp.QuadPart = (now.QuadPart - m_start.QuadPart) * 1000;
 | 
			
		||||
 | 
			
		||||
	return (unsigned int)(temp.QuadPart / m_frequency.QuadPart);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
 | 
			
		||||
CStopWatch::CStopWatch() :
 | 
			
		||||
m_start()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CStopWatch::~CStopWatch()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned long CStopWatch::start()
 | 
			
		||||
{
 | 
			
		||||
	::gettimeofday(&m_start, NULL);
 | 
			
		||||
 | 
			
		||||
	return m_start.tv_usec;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int CStopWatch::elapsed()
 | 
			
		||||
{
 | 
			
		||||
	struct timeval now;
 | 
			
		||||
	::gettimeofday(&now, NULL);
 | 
			
		||||
 | 
			
		||||
	unsigned int elapsed = (now.tv_sec - m_start.tv_sec) * 1000U;
 | 
			
		||||
	elapsed += now.tv_usec / 1000U;
 | 
			
		||||
	elapsed -= m_start.tv_usec / 1000U;
 | 
			
		||||
 | 
			
		||||
	return elapsed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										46
									
								
								P25Parrot/StopWatch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								P25Parrot/StopWatch.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(STOPWATCH_H)
 | 
			
		||||
#define	STOPWATCH_H
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class CStopWatch
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	CStopWatch();
 | 
			
		||||
	~CStopWatch();
 | 
			
		||||
 | 
			
		||||
	unsigned long start();
 | 
			
		||||
	unsigned int  elapsed();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	LARGE_INTEGER  m_frequency;
 | 
			
		||||
	LARGE_INTEGER  m_start;
 | 
			
		||||
#else
 | 
			
		||||
	struct timeval m_start;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										68
									
								
								P25Parrot/Timer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								P25Parrot/Timer.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,68 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2009,2010,2015 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "Timer.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
CTimer::CTimer(unsigned int ticksPerSec, unsigned int secs, unsigned int msecs) :
 | 
			
		||||
m_ticksPerSec(ticksPerSec),
 | 
			
		||||
m_timeout(0U),
 | 
			
		||||
m_timer(0U)
 | 
			
		||||
{
 | 
			
		||||
	assert(ticksPerSec > 0U);
 | 
			
		||||
 | 
			
		||||
	if (secs > 0U || msecs > 0U) {
 | 
			
		||||
		// m_timeout = ((secs * 1000U + msecs) * m_ticksPerSec) / 1000U + 1U;
 | 
			
		||||
		unsigned long long temp = (secs * 1000ULL + msecs) * m_ticksPerSec;
 | 
			
		||||
		m_timeout = (unsigned int)(temp / 1000ULL + 1ULL);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CTimer::~CTimer()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CTimer::setTimeout(unsigned int secs, unsigned int msecs)
 | 
			
		||||
{
 | 
			
		||||
	if (secs > 0U || msecs > 0U) {
 | 
			
		||||
		// m_timeout = ((secs * 1000U + msecs) * m_ticksPerSec) / 1000U + 1U;
 | 
			
		||||
		unsigned long long temp = (secs * 1000ULL + msecs) * m_ticksPerSec;
 | 
			
		||||
		m_timeout = (unsigned int)(temp / 1000ULL + 1ULL);
 | 
			
		||||
	} else {
 | 
			
		||||
		m_timeout = 0U;
 | 
			
		||||
		m_timer = 0U;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int CTimer::getTimeout() const
 | 
			
		||||
{
 | 
			
		||||
	if (m_timeout == 0U)
 | 
			
		||||
		return 0U;
 | 
			
		||||
 | 
			
		||||
	return (m_timeout - 1U) / m_ticksPerSec;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int CTimer::getTimer() const
 | 
			
		||||
{
 | 
			
		||||
	if (m_timer == 0U)
 | 
			
		||||
		return 0U;
 | 
			
		||||
 | 
			
		||||
	return (m_timer - 1U) / m_ticksPerSec;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										89
									
								
								P25Parrot/Timer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								P25Parrot/Timer.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2009,2010,2011,2014 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef	Timer_H
 | 
			
		||||
#define	Timer_H
 | 
			
		||||
 | 
			
		||||
class CTimer {
 | 
			
		||||
public:
 | 
			
		||||
	CTimer(unsigned int ticksPerSec, unsigned int secs = 0U, unsigned int msecs = 0U);
 | 
			
		||||
	~CTimer();
 | 
			
		||||
 | 
			
		||||
	void setTimeout(unsigned int secs, unsigned int msecs = 0U);
 | 
			
		||||
 | 
			
		||||
	unsigned int getTimeout() const;
 | 
			
		||||
	unsigned int getTimer() const;
 | 
			
		||||
 | 
			
		||||
	unsigned int getRemaining()
 | 
			
		||||
	{
 | 
			
		||||
		if (m_timeout == 0U || m_timer == 0U)
 | 
			
		||||
			return 0U;
 | 
			
		||||
 | 
			
		||||
		if (m_timer >= m_timeout)
 | 
			
		||||
			return 0U;
 | 
			
		||||
 | 
			
		||||
		return (m_timeout - m_timer) / m_ticksPerSec;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool isRunning()
 | 
			
		||||
	{
 | 
			
		||||
		return m_timer > 0U;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void start(unsigned int secs, unsigned int msecs = 0U)
 | 
			
		||||
	{
 | 
			
		||||
		setTimeout(secs, msecs);
 | 
			
		||||
 | 
			
		||||
		start();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void start()
 | 
			
		||||
	{
 | 
			
		||||
		if (m_timeout > 0U)
 | 
			
		||||
			m_timer = 1U;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void stop()
 | 
			
		||||
	{
 | 
			
		||||
		m_timer = 0U;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool hasExpired()
 | 
			
		||||
	{
 | 
			
		||||
		if (m_timeout == 0U || m_timer == 0U)
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		if (m_timer >= m_timeout)
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void clock(unsigned int ticks = 1U)
 | 
			
		||||
	{
 | 
			
		||||
		if (m_timer > 0U && m_timeout > 0U)
 | 
			
		||||
			m_timer += ticks;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	unsigned int m_ticksPerSec;
 | 
			
		||||
	unsigned int m_timeout;
 | 
			
		||||
	unsigned int m_timer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										261
									
								
								P25Parrot/UDPSocket.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										261
									
								
								P25Parrot/UDPSocket.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,261 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2006-2016 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "UDPSocket.h"
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
#if !defined(_WIN32) && !defined(_WIN64)
 | 
			
		||||
#include <cerrno>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) :
 | 
			
		||||
m_address(address),
 | 
			
		||||
m_port(port),
 | 
			
		||||
m_fd(-1)
 | 
			
		||||
{
 | 
			
		||||
	assert(!address.empty());
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	WSAData data;
 | 
			
		||||
	int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data);
 | 
			
		||||
	if (wsaRet != 0)
 | 
			
		||||
		::fprintf(stderr, "Error from WSAStartup\n");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CUDPSocket::CUDPSocket(unsigned int port) :
 | 
			
		||||
m_address(),
 | 
			
		||||
m_port(port),
 | 
			
		||||
m_fd(-1)
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	WSAData data;
 | 
			
		||||
	int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data);
 | 
			
		||||
	if (wsaRet != 0)
 | 
			
		||||
		::fprintf(stderr, "Error from WSAStartup\n");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CUDPSocket::~CUDPSocket()
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	::WSACleanup();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
in_addr CUDPSocket::lookup(const std::string& hostname)
 | 
			
		||||
{
 | 
			
		||||
	in_addr addr;
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	unsigned long address = ::inet_addr(hostname.c_str());
 | 
			
		||||
	if (address != INADDR_NONE && address != INADDR_ANY) {
 | 
			
		||||
		addr.s_addr = address;
 | 
			
		||||
		return addr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct hostent* hp = ::gethostbyname(hostname.c_str());
 | 
			
		||||
	if (hp != NULL) {
 | 
			
		||||
		::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr));
 | 
			
		||||
		return addr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	::fprintf(stderr, "Cannot find address for host %s\n", hostname.c_str());
 | 
			
		||||
 | 
			
		||||
	addr.s_addr = INADDR_NONE;
 | 
			
		||||
	return addr;
 | 
			
		||||
#else
 | 
			
		||||
	in_addr_t address = ::inet_addr(hostname.c_str());
 | 
			
		||||
	if (address != in_addr_t(-1)) {
 | 
			
		||||
		addr.s_addr = address;
 | 
			
		||||
		return addr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct hostent* hp = ::gethostbyname(hostname.c_str());
 | 
			
		||||
	if (hp != NULL) {
 | 
			
		||||
		::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr));
 | 
			
		||||
		return addr;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	::fprintf(stderr, "Cannot find address for host %s\n", hostname.c_str());
 | 
			
		||||
 | 
			
		||||
	addr.s_addr = INADDR_NONE;
 | 
			
		||||
	return addr;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CUDPSocket::open()
 | 
			
		||||
{
 | 
			
		||||
	m_fd = ::socket(PF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
	if (m_fd < 0) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
		::fprintf(stderr, "Cannot create the UDP socket, err: %lu\n", ::GetLastError());
 | 
			
		||||
#else
 | 
			
		||||
		::fprintf(stderr, "Cannot create the UDP socket, err: %d\n", errno);
 | 
			
		||||
#endif
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (m_port > 0U) {
 | 
			
		||||
		sockaddr_in addr;
 | 
			
		||||
		::memset(&addr, 0x00, sizeof(sockaddr_in));
 | 
			
		||||
		addr.sin_family      = AF_INET;
 | 
			
		||||
		addr.sin_port        = htons(m_port);
 | 
			
		||||
		addr.sin_addr.s_addr = htonl(INADDR_ANY);
 | 
			
		||||
 | 
			
		||||
		if (!m_address.empty()) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
			addr.sin_addr.s_addr = ::inet_addr(m_address.c_str());
 | 
			
		||||
#else
 | 
			
		||||
			addr.sin_addr.s_addr = ::inet_addr(m_address.c_str());
 | 
			
		||||
#endif
 | 
			
		||||
			if (addr.sin_addr.s_addr == INADDR_NONE) {
 | 
			
		||||
				::fprintf(stderr, "The local address is invalid - %s\n", m_address.c_str());
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int reuse = 1;
 | 
			
		||||
		if (::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
			::fprintf(stderr, "Cannot set the UDP socket option, err: %lu\n", ::GetLastError());
 | 
			
		||||
#else
 | 
			
		||||
			::fprintf(stderr, "Cannot set the UDP socket option, err: %d\n", errno);
 | 
			
		||||
#endif
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (::bind(m_fd, (sockaddr*)&addr, sizeof(sockaddr_in)) == -1) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
			::fprintf(stderr, "Cannot bind the UDP address, err: %lu\n", ::GetLastError());
 | 
			
		||||
#else
 | 
			
		||||
			::fprintf(stderr, "Cannot bind the UDP address, err: %d\n", errno);
 | 
			
		||||
#endif
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int CUDPSocket::read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port)
 | 
			
		||||
{
 | 
			
		||||
	assert(buffer != NULL);
 | 
			
		||||
	assert(length > 0U);
 | 
			
		||||
 | 
			
		||||
	// Check that the readfrom() won't block
 | 
			
		||||
	fd_set readFds;
 | 
			
		||||
	FD_ZERO(&readFds);
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	FD_SET((unsigned int)m_fd, &readFds);
 | 
			
		||||
#else
 | 
			
		||||
	FD_SET(m_fd, &readFds);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// Return immediately
 | 
			
		||||
	timeval tv;
 | 
			
		||||
	tv.tv_sec  = 0L;
 | 
			
		||||
	tv.tv_usec = 0L;
 | 
			
		||||
 | 
			
		||||
	int ret = ::select(m_fd + 1, &readFds, NULL, NULL, &tv);
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
		::fprintf(stderr, "Error returned from UDP select, err: %lu\n", ::GetLastError());
 | 
			
		||||
#else
 | 
			
		||||
		::fprintf(stderr, "Error returned from UDP select, err: %d\n", errno);
 | 
			
		||||
#endif
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ret == 0)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	sockaddr_in addr;
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	int size = sizeof(sockaddr_in);
 | 
			
		||||
#else
 | 
			
		||||
	socklen_t size = sizeof(sockaddr_in);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	int len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&addr, &size);
 | 
			
		||||
#else
 | 
			
		||||
	ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&addr, &size);
 | 
			
		||||
#endif
 | 
			
		||||
	if (len <= 0) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
		::fprintf(stderr, "Error returned from recvfrom, err: %lu\n", ::GetLastError());
 | 
			
		||||
#else
 | 
			
		||||
		::fprintf(stderr, "Error returned from recvfrom, err: %d\n", errno);
 | 
			
		||||
#endif
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	address = addr.sin_addr;
 | 
			
		||||
	port    = ntohs(addr.sin_port);
 | 
			
		||||
 | 
			
		||||
	return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port)
 | 
			
		||||
{
 | 
			
		||||
	assert(buffer != NULL);
 | 
			
		||||
	assert(length > 0U);
 | 
			
		||||
 | 
			
		||||
	sockaddr_in addr;
 | 
			
		||||
	::memset(&addr, 0x00, sizeof(sockaddr_in));
 | 
			
		||||
 | 
			
		||||
	addr.sin_family = AF_INET;
 | 
			
		||||
	addr.sin_addr   = address;
 | 
			
		||||
	addr.sin_port   = htons(port);
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	int ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, sizeof(sockaddr_in));
 | 
			
		||||
#else
 | 
			
		||||
	ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, sizeof(sockaddr_in));
 | 
			
		||||
#endif
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
		::fprintf(stderr, "Error returned from sendto, err: %lu\n", ::GetLastError());
 | 
			
		||||
#else
 | 
			
		||||
		::fprintf(stderr, "Error returned from sendto, err: %d\n", errno);
 | 
			
		||||
#endif
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	if (ret != int(length))
 | 
			
		||||
		return false;
 | 
			
		||||
#else
 | 
			
		||||
	if (ret != ssize_t(length))
 | 
			
		||||
		return false;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CUDPSocket::close()
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32) || defined(_WIN64)
 | 
			
		||||
	::closesocket(m_fd);
 | 
			
		||||
#else
 | 
			
		||||
	::close(m_fd);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								P25Parrot/UDPSocket.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								P25Parrot/UDPSocket.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,58 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2009-2011,2013,2015,2016 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef UDPSocket_H
 | 
			
		||||
#define UDPSocket_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#if !defined(_WIN32) && !defined(_WIN64)
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#else
 | 
			
		||||
#include <winsock.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
class CUDPSocket {
 | 
			
		||||
public:
 | 
			
		||||
	CUDPSocket(const std::string& address, unsigned int port = 0U);
 | 
			
		||||
	CUDPSocket(unsigned int port = 0U);
 | 
			
		||||
	~CUDPSocket();
 | 
			
		||||
 | 
			
		||||
	bool open();
 | 
			
		||||
 | 
			
		||||
	int  read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port);
 | 
			
		||||
	bool write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port);
 | 
			
		||||
 | 
			
		||||
	void close();
 | 
			
		||||
 | 
			
		||||
	static in_addr lookup(const std::string& hostName);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	std::string    m_address;
 | 
			
		||||
	unsigned short m_port;
 | 
			
		||||
	int            m_fd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										145
									
								
								P25Parrot/Utils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								P25Parrot/Utils.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,145 @@
 | 
			
		||||
/*
 | 
			
		||||
 *	Copyright (C) 2009,2014,2015,2016 Jonathan Naylor, G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *	This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *	it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *	the Free Software Foundation; version 2 of the License.
 | 
			
		||||
 *
 | 
			
		||||
 *	This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *	GNU General Public License for more details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "Utils.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
void CUtils::dump(const std::string& title, const unsigned char* data, unsigned int length)
 | 
			
		||||
{
 | 
			
		||||
	assert(data != NULL);
 | 
			
		||||
 | 
			
		||||
	dump(2U, title, data, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CUtils::dump(int level, const std::string& title, const unsigned char* data, unsigned int length)
 | 
			
		||||
{
 | 
			
		||||
	assert(data != NULL);
 | 
			
		||||
 | 
			
		||||
	::fprintf(stdout, "%s\n", title.c_str());
 | 
			
		||||
 | 
			
		||||
	unsigned int offset = 0U;
 | 
			
		||||
 | 
			
		||||
	while (length > 0U) {
 | 
			
		||||
		std::string output;
 | 
			
		||||
 | 
			
		||||
		unsigned int bytes = (length > 16U) ? 16U : length;
 | 
			
		||||
 | 
			
		||||
		for (unsigned i = 0U; i < bytes; i++) {
 | 
			
		||||
			char temp[10U];
 | 
			
		||||
			::sprintf(temp, "%02X ", data[offset + i]);
 | 
			
		||||
			output += temp;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (unsigned int i = bytes; i < 16U; i++)
 | 
			
		||||
			output += "   ";
 | 
			
		||||
 | 
			
		||||
		output += "   *";
 | 
			
		||||
 | 
			
		||||
		for (unsigned i = 0U; i < bytes; i++) {
 | 
			
		||||
			unsigned char c = data[offset + i];
 | 
			
		||||
 | 
			
		||||
			if (::isprint(c))
 | 
			
		||||
				output += c;
 | 
			
		||||
			else
 | 
			
		||||
				output += '.';
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		output += '*';
 | 
			
		||||
 | 
			
		||||
		::fprintf(stdout, "%04X:  %s\n", offset, output.c_str());
 | 
			
		||||
 | 
			
		||||
		offset += 16U;
 | 
			
		||||
 | 
			
		||||
		if (length >= 16U)
 | 
			
		||||
			length -= 16U;
 | 
			
		||||
		else
 | 
			
		||||
			length = 0U;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CUtils::dump(const std::string& title, const bool* bits, unsigned int length)
 | 
			
		||||
{
 | 
			
		||||
	assert(bits != NULL);
 | 
			
		||||
 | 
			
		||||
	dump(2U, title, bits, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CUtils::dump(int level, const std::string& title, const bool* bits, unsigned int length)
 | 
			
		||||
{
 | 
			
		||||
	assert(bits != NULL);
 | 
			
		||||
 | 
			
		||||
	unsigned char bytes[100U];
 | 
			
		||||
	unsigned int nBytes = 0U;
 | 
			
		||||
	for (unsigned int n = 0U; n < length; n += 8U, nBytes++)
 | 
			
		||||
		bitsToByteBE(bits + n, bytes[nBytes]);
 | 
			
		||||
 | 
			
		||||
	dump(level, title, bytes, nBytes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CUtils::byteToBitsBE(unsigned char byte, bool* bits)
 | 
			
		||||
{
 | 
			
		||||
	assert(bits != NULL);
 | 
			
		||||
 | 
			
		||||
	bits[0U] = (byte & 0x80U) == 0x80U;
 | 
			
		||||
	bits[1U] = (byte & 0x40U) == 0x40U;
 | 
			
		||||
	bits[2U] = (byte & 0x20U) == 0x20U;
 | 
			
		||||
	bits[3U] = (byte & 0x10U) == 0x10U;
 | 
			
		||||
	bits[4U] = (byte & 0x08U) == 0x08U;
 | 
			
		||||
	bits[5U] = (byte & 0x04U) == 0x04U;
 | 
			
		||||
	bits[6U] = (byte & 0x02U) == 0x02U;
 | 
			
		||||
	bits[7U] = (byte & 0x01U) == 0x01U;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CUtils::byteToBitsLE(unsigned char byte, bool* bits)
 | 
			
		||||
{
 | 
			
		||||
	assert(bits != NULL);
 | 
			
		||||
 | 
			
		||||
	bits[0U] = (byte & 0x01U) == 0x01U;
 | 
			
		||||
	bits[1U] = (byte & 0x02U) == 0x02U;
 | 
			
		||||
	bits[2U] = (byte & 0x04U) == 0x04U;
 | 
			
		||||
	bits[3U] = (byte & 0x08U) == 0x08U;
 | 
			
		||||
	bits[4U] = (byte & 0x10U) == 0x10U;
 | 
			
		||||
	bits[5U] = (byte & 0x20U) == 0x20U;
 | 
			
		||||
	bits[6U] = (byte & 0x40U) == 0x40U;
 | 
			
		||||
	bits[7U] = (byte & 0x80U) == 0x80U;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte)
 | 
			
		||||
{
 | 
			
		||||
	assert(bits != NULL);
 | 
			
		||||
 | 
			
		||||
	byte  = bits[0U] ? 0x80U : 0x00U;
 | 
			
		||||
	byte |= bits[1U] ? 0x40U : 0x00U;
 | 
			
		||||
	byte |= bits[2U] ? 0x20U : 0x00U;
 | 
			
		||||
	byte |= bits[3U] ? 0x10U : 0x00U;
 | 
			
		||||
	byte |= bits[4U] ? 0x08U : 0x00U;
 | 
			
		||||
	byte |= bits[5U] ? 0x04U : 0x00U;
 | 
			
		||||
	byte |= bits[6U] ? 0x02U : 0x00U;
 | 
			
		||||
	byte |= bits[7U] ? 0x01U : 0x00U;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte)
 | 
			
		||||
{
 | 
			
		||||
	assert(bits != NULL);
 | 
			
		||||
 | 
			
		||||
	byte  = bits[0U] ? 0x01U : 0x00U;
 | 
			
		||||
	byte |= bits[1U] ? 0x02U : 0x00U;
 | 
			
		||||
	byte |= bits[2U] ? 0x04U : 0x00U;
 | 
			
		||||
	byte |= bits[3U] ? 0x08U : 0x00U;
 | 
			
		||||
	byte |= bits[4U] ? 0x10U : 0x00U;
 | 
			
		||||
	byte |= bits[5U] ? 0x20U : 0x00U;
 | 
			
		||||
	byte |= bits[6U] ? 0x40U : 0x00U;
 | 
			
		||||
	byte |= bits[7U] ? 0x80U : 0x00U;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								P25Parrot/Utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								P25Parrot/Utils.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,36 @@
 | 
			
		||||
/*
 | 
			
		||||
 *	Copyright (C) 2009,2014,2015 by Jonathan Naylor, G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *	This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *	it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *	the Free Software Foundation; version 2 of the License.
 | 
			
		||||
 *
 | 
			
		||||
 *	This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *	GNU General Public License for more details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef	Utils_H
 | 
			
		||||
#define	Utils_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
class CUtils {
 | 
			
		||||
public:
 | 
			
		||||
	static void dump(const std::string& title, const unsigned char* data, unsigned int length);
 | 
			
		||||
	static void dump(int level, const std::string& title, const unsigned char* data, unsigned int length);
 | 
			
		||||
 | 
			
		||||
	static void dump(const std::string& title, const bool* bits, unsigned int length);
 | 
			
		||||
	static void dump(int level, const std::string& title, const bool* bits, unsigned int length);
 | 
			
		||||
 | 
			
		||||
	static void byteToBitsBE(unsigned char byte, bool* bits);
 | 
			
		||||
	static void byteToBitsLE(unsigned char byte, bool* bits);
 | 
			
		||||
 | 
			
		||||
	static void bitsToByteBE(const bool* bits, unsigned char& byte);
 | 
			
		||||
	static void bitsToByteLE(const bool* bits, unsigned char& byte);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										24
									
								
								P25Parrot/Version.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								P25Parrot/Version.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
			
		||||
/*
 | 
			
		||||
 *   Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *   the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 *   (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is distributed in the hope that it will be useful,
 | 
			
		||||
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *   GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *   You should have received a copy of the GNU General Public License
 | 
			
		||||
 *   along with this program; if not, write to the Free Software
 | 
			
		||||
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(VERSION_H)
 | 
			
		||||
#define	VERSION_H
 | 
			
		||||
 | 
			
		||||
const char* VERSION = "20161003";
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user