Skip to content
Snippets Groups Projects
Commit bad24bcd authored by David Wehr's avatar David Wehr
Browse files

Reorganized WiFi bridge folder and added Windows serial testing utility

parent ba89b949
No related branches found
No related tags found
No related merge requests found
Showing
with 1227 additions and 0 deletions
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
*.vcxproj.filters
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/

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}") = "SerialEchoConsole", "SerialEchoConsole\SerialEchoConsole.vcxproj", "{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}"
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
{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}.Debug|x64.ActiveCfg = Debug|x64
{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}.Debug|x64.Build.0 = Debug|x64
{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}.Debug|x86.ActiveCfg = Debug|Win32
{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}.Debug|x86.Build.0 = Debug|Win32
{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}.Release|x64.ActiveCfg = Release|x64
{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}.Release|x64.Build.0 = Release|x64
{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}.Release|x86.ActiveCfg = Release|Win32
{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
#include "stdafx.h"
#include "Packet.hpp"
#include <algorithm>
#include <iostream>
#include <sstream>
#include <chrono>
using namespace std;
Packet::Packet() {
isValid = false;
}
Packet::Packet(uint8_t _type, uint8_t _subtype, uint16_t _id,
const vector<unsigned char>& _payload)
: type{ _type }
, subtype{ _subtype }
, id{ _id }
, payload{ _payload }
, isValid{ true } {
checksum = 0xBE;
checksum ^= type;
checksum ^= subtype;
checksum ^= (id >> 8);
checksum ^= (id & 0xFF);
checksum ^= (payload.size() >> 8) & 0xFF;
checksum ^= (payload.size() & 0xFF);
for (auto& byte : payload) {
checksum ^= byte;
}
}
Packet::operator bool() const {
return isValid;
}
string Packet::toString() const {
stringstream ss;
ss << "[ID]\t" + to_string(id) +
"\n[Type]\t" + to_string(type) +
"\n[Subtype]\t" + to_string(subtype) +
"\n[Length]\t" + to_string(payload.size()) +
"\n[Payload]\t{ ";
for (auto& byte : payload) {
ss << std::hex << (int)byte << " ";
}
ss << "}";
return ss.str();
}
vector<unsigned char> Packet::toVector() const {
vector<unsigned char> buf({ 0xBE, type, subtype, static_cast<uint8_t>(id & 0xFF), static_cast<uint8_t>(id >> 8) });
buf.insert(buf.end(), payload.begin(), payload.end());
buf.push_back(checksum);
return buf;
}
vector<Packet> parsePacket(const vector<unsigned char>& bytes) {
static vector<unsigned char> savedBytes;
static uint16_t id = 0;
static bool first = true;
static chrono::high_resolution_clock::time_point lastTime;
if (bytes.size() == 0)
return vector<Packet>();
/*
auto now = chrono::high_resolution_clock::now();
if (first) {
first = false;
}
else {
auto durationMs = chrono::duration_cast<chrono::microseconds>(now - lastTime);
double us = chrono::duration<double, micro>(durationMs).count();
double baudrate = 10000000. * bytes.size() / us;
if (baudrate > (640. / 0.005)) {
cout << us << endl;
cout << "[Warning] High baud rate: " << baudrate << endl;
}
}
lastTime = now;
*/
if (bytes.size() > 64)
cout << '|';
vector<Packet> foundPackets;
savedBytes.insert(savedBytes.end(), bytes.begin(), bytes.end());
Packet p;
while ((p = findPacket(savedBytes))) {
foundPackets.push_back(p);
if (p.id != id) {
cout << "[Warning] Unexpected packet ID (received " << p.id << ", expected " << id << "):\n" << p.toString() << endl;
}
id = p.id + 1;
}
return foundPackets;
}
Packet findPacket(vector<unsigned char>& bytes) {
static bool largePacket = false;
Packet found;
static chrono::high_resolution_clock::time_point lastTime = chrono::high_resolution_clock::now();
static double timeFilter = 50.;
if (bytes.size() == 0)
return found;
//Find start byte
unsigned int i;
for (i = 0; i < bytes.size() && bytes[i] != 0xBE; ++i);
if (i == bytes.size()) {
//No start byte
cout << "Removing junk data (" << i << " bytes)" << endl;
bytes.clear();
return found;
}
//Remove junk data
if (i != 0) {
std::cout << "Removing junk data (" << i << " bytes)" << std::endl;
bytes.erase(bytes.begin(), bytes.begin() + i);
}
if (bytes.size() >= 7) {
uint16_t length = bytes[5] | (bytes[6] << 8);
if (length > 100 && !largePacket) {
largePacket = true;
cout << "[Warning] Receiving large packet (size " << length << ")" << endl;
}
if (bytes.size() >= (8 + length)) {
//We have a full packet!
vector<unsigned char> payload(bytes.begin() + 7, bytes.begin() + 7 + length);
found = Packet(bytes[1], bytes[2], bytes[3] | (bytes[4] << 8), payload);
if (found.checksum != bytes[7 + length]) {
cout << "[Error] Invalid checksum:\n" << found.toString();
found.isValid = false;
}
//Remove the packet data
bytes.erase(bytes.begin(), bytes.begin() + 8 + length);
//Clear the large packet flag
largePacket = false;
auto now = chrono::high_resolution_clock::now();
auto ms = chrono::duration_cast<chrono::milliseconds>(now - lastTime);
double duration = chrono::duration<double, milli>(ms).count();
double baud = 10000. * (8 + length) / duration;
if (duration > (2 * timeFilter)) {
cout << "[Warning] Jitter: Average duration " << (int)timeFilter << "ms, this one " << (int)duration << "ms" << endl;
}
timeFilter = timeFilter*0.5 + duration*0.5;
lastTime = now;
}
}
return found;
}
\ No newline at end of file
#pragma once
#include <vector>
#include <string>
#include <stdint.h>
struct Packet
{
Packet();
Packet(uint8_t type, uint8_t subtype, uint16_t id,
const std::vector<unsigned char>& payload);
operator bool() const;
std::string toString() const;
std::vector<unsigned char> toVector() const;
uint8_t type, subtype;
uint16_t id;
//uint16_t length;
std::vector<unsigned char> payload;
uint8_t checksum;
bool isValid;
};
std::vector<Packet> parsePacket(const std::vector<unsigned char>&);
Packet findPacket(std::vector<unsigned char>&);
\ No newline at end of file
========================================================================
CONSOLE APPLICATION : SerialEchoConsole Project Overview
========================================================================
AppWizard has created this SerialEchoConsole application for you.
This file contains a summary of what you will find in each of the files that
make up your SerialEchoConsole application.
SerialEchoConsole.vcxproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
SerialEchoConsole.vcxproj.filters
This is the filters file for VC++ projects generated using an Application Wizard.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
SerialEchoConsole.cpp
This is the main application source file.
/////////////////////////////////////////////////////////////////////////////
Other standard files:
StdAfx.h, StdAfx.cpp
These files are used to build a precompiled header (PCH) file
named SerialEchoConsole.pch and a precompiled types file named StdAfx.obj.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SerialPort.h"
#include "Packet.hpp"
#include <conio.h>
#include <thread>
#include <iostream>
#include <iomanip>
#include <string>
#include <chrono>
#define SEND_SIZE 512
#define DELAY 10
void printHex(std::vector<unsigned char> data) {
for (int i = 0; i < SEND_SIZE; i++) {
std::cout << std::setw(2) << std::hex << (int)data[i] << ":";
}
}
int n_matches = 0;
int main(int argc, char* argv[]) {
if (argc != 3) {
std::cout << "[Error] Usage: " << argv[0]
<< " [Comm Port] [baud]" << std::endl;
return -1;
}
/*
std::vector<unsigned char> testData({ 0x00, 0xBE, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF });
while (true) {
for (auto& byte : testData) {
auto packets = parsePacket({ byte });
for (auto& packet : packets) {
//std::cout << "[Info] Found packet with type " << (int)packet.type
//<< " and length " << (int)packet.payload.size() << std::endl;
std::cout << "Found packet:\n" << packet.toString() << "\n" << std::endl;
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
*/
int port = std::stoi(std::string(argv[1])),
baud = std::stoi(std::string(argv[2]));
//Create SerialPort object
SerialPort serial(port, baud);
//Connect to serial device
try {
serial.Connect();
}
catch (const std::exception& e) {
std::cout << "[Error] trying to connect: " << e.what() << std::endl;
return -1;
}
while (serial.IsConnected()) {
auto packets = parsePacket(serial.Read());
for (auto& packet : packets) {
std::cout << '.';
//std::cout << "Found packet:\n" << packet.toString() << "\n" << std::endl;
}
}
/*
std::vector<unsigned char> send_data;
for (int i = 0; i < SEND_SIZE; i++) {
send_data.push_back(i % 256);
}
std::vector<unsigned char> recvd_data;
std::chrono::milliseconds last_sent = std::chrono::milliseconds(0);
while (serial.IsConnected()) {
std::chrono::milliseconds now_time = std::chrono::duration_cast< std::chrono::milliseconds >(
std::chrono::system_clock::now().time_since_epoch());
if ((now_time - last_sent) > std::chrono::milliseconds(DELAY)) {
serial.Send(send_data);
last_sent = now_time;
}
auto read = serial.Read();
recvd_data.insert(recvd_data.end(), read.begin(), read.end());
if (recvd_data.size() >= SEND_SIZE) {
bool matches = true;
for (int i = 0; i < SEND_SIZE; i++) {
if (recvd_data[i] != send_data[i]) {
matches = false;
}
}
if (!matches) {
std::cout << "Mismatch on receive" << std::endl;
std::cout << "Successfully matched " << n_matches << std::endl;
std::cout << "Expected ";
printHex(send_data);
std::cout << std::endl;
std::cout << "Received ";
printHex(recvd_data);
std::cout << std::endl;
}
else {
std::cout << "Matches" << std::endl;
n_matches++;
}
recvd_data = { recvd_data.begin() + SEND_SIZE, recvd_data.end() };
}
if (kbhit()) {
exit(0);
//unsigned char c = (unsigned char)getch();
//serial.Send({ c });
//std::cout << "Sent " << c << std::endl;
}
}
*/
return 0;
}
<?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>{C2ACDB47-A077-43EB-AA59-DD7E33DEAEE2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SerialEchoConsole</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>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</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>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</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>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</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>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Packet.hpp" />
<ClInclude Include="SerialPort.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Packet.cpp" />
<ClCompile Include="SerialEchoConsole.cpp" />
<ClCompile Include="SerialPort.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
#include "stdafx.h"
#include "SerialPort.h"
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
SerialPort::SerialPort(unsigned char id, unsigned int baud) {
comHandle = INVALID_HANDLE_VALUE;
connected = false;
this->port = id;
this->baud = baud;
//Connect();
}
void SerialPort::Connect() {
DCB dcb;
COMMTIMEOUTS timeouts;
std::string portName = "\\\\.\\COM" + std::to_string(port);
if (connected || (comHandle != INVALID_HANDLE_VALUE))
throw Exception("SerialPort already connected.");
comHandle = CreateFile(portName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (comHandle == INVALID_HANDLE_VALUE)
throw Exception("Unable to open COM port.");
GetCommState(comHandle, &dcb);
dcb.BaudRate = baud;
dcb.fBinary = 1;
dcb.Parity = NOPARITY;
dcb.StopBits = TWOSTOPBITS;
dcb.ByteSize = 8;
if (!SetCommState(comHandle, &dcb)) {
Disconnect();
throw Exception("Unable to set COM port parameters.");
}
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 1;
if (!SetCommTimeouts(comHandle, &timeouts)) {
Disconnect();
throw Exception("Unable to set COM port timeouts.");
}
connected = true;
}
void SerialPort::Disconnect() {
if (!connected)
return;
CloseHandle(comHandle);
comHandle = INVALID_HANDLE_VALUE;
connected = false;
}
bool SerialPort::IsConnected() {
return connected;
}
void SerialPort::Send(std::vector<unsigned char> data) {
DWORD nWritten;
unsigned int totalSent = 0, attempts = 0;
if (!IsConnected())
throw Exception("SerialPort not connected.");
while (totalSent < data.size()) {
bool failed = false;
if (!WriteFile(comHandle, (LPCVOID)(data.data() + totalSent), data.size() - totalSent, &nWritten, NULL))
failed = true;
if (attempts++ > 10)
failed = true;
if (failed) {
Disconnect();
throw Exception("Unable to send data.");
}
totalSent += nWritten;
}
}
std::vector<unsigned char> SerialPort::Read() {
if (!IsConnected())
throw Exception("SerialPort not connected.");
DWORD nRead;
unsigned char buffer[32];
if (!ReadFile(comHandle, (LPVOID)buffer, 32, &nRead, NULL)) {
Disconnect();
throw Exception("Unable to receive data.");
}
std::vector<unsigned char> data;
data.assign(buffer, buffer + nRead);
return data;
}
SerialPort::~SerialPort() {
if (IsConnected())
Disconnect();
}
\ No newline at end of file
#pragma once
#include <vector>
#include <string>
#include <Windows.h>
#include <exception>
class SerialPort {
public:
static const int ERROR_SETTING_COMM_SETTINGS = -1;
static const int ERROR_SETTING_COMM_TIMEOUTS = -2;
static const int ERROR_OPENING_COMM_PORT = -3;
static const int ERROR_SENDING_COMM = -4;
static const int ERROR_PORT_NOT_READY = -5;
static const int ERROR_GENERIC_WRITE_FAIL = -6;
static const int ERROR_GENERIC_READ_FAIL = -7;
static const int ERROR_GIVEN_NULL_POINTER = -8;
class Exception : std::exception {
public:
Exception(std::string message) { _msg = std::string("SerialPort Exception: " + message); }
virtual const char *what() { return _msg.c_str(); }
private:
std::string _msg;
};
SerialPort(unsigned char id, unsigned int baud);
void Connect();
void Disconnect();
bool IsConnected();
void Send(std::vector<unsigned char> data);
std::vector<unsigned char> Read();
~SerialPort();
private:
HANDLE comHandle;
unsigned int baud, port;
bool connected;
};
\ No newline at end of file
// stdafx.cpp : source file that includes just the standard includes
// SerialEchoConsole.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>
extern "C" {
#include "user_interface.h"
#include "circ_buffer.h"
}
#include <ESP8266WiFi.h>
#include <algorithm>
char ssid[] = "uCart_AP"; // Network name of hosted network
char pass[] = "password";
IPAddress client_ip;
unsigned int tcp_port = 8080;
// Server object for listening for requests
WiFiServer server(tcp_port);
// Reusable client object to communicate with the connected client
WiFiClient client;
// Maximum number of bytes to read at a time
const int BUF_SIZE = 1024;
byte* tcp_in_buffer = new byte[BUF_SIZE];
//byte tcp_in_buffer[BUF_SIZE];
//byte serial_in_buf[BUF_SIZE];
byte* serial_in_buf = new byte[BUF_SIZE];
//byte dummy_data[400];
byte* dummy_data = new byte[BUF_SIZE];
const int SEND_BUF_SIZE = 1024;
void setup() {
// Set baud rate for UART
Serial.begin(115200);
Serial.setTimeout(2000);
Serial.setRxBufferSize(1024);
//Serial.print("Serial TX buffer size: ");
Serial.println(Serial.availableForWrite());
pinMode(0, OUTPUT);
pinMode(2, OUTPUT);
digitalWrite(2, LOW);
/*
WiFiEventHandler client_disconnected_handler = WiFi.onSoftAPModeStationDisconnected(
[](const WiFiEventSoftAPModeStationDisconnected& event) {
//Serial.println("disconnected");
});
*/
// Configure chip to be access point
WiFi.mode(WIFI_AP);
// Wait for Access point to be created
while (!WiFi.softAP(ssid)) {
delay(500); // Wait half a second before re-trying
}
waitForStation();
// Begin TCP on a particular port
server.begin();
server.setNoDelay(true);
}
void waitForStation() {
// Wait for a client to connect
struct station_info* connected_stns = NULL;
while (connected_stns = wifi_softap_get_station_info(), !connected_stns) {
delay(500);
}
client_ip = IPAddress(IP2STR(&connected_stns->ip));
wifi_softap_free_station_info();
}
int led_on = 0;
int loop_count = 0;
void loop() {
if (!(loop_count % 5000)) {
digitalWrite(0, led_on ? HIGH : LOW);
led_on = !led_on;
}
loop_count++;
// Assume only one client will connect at a time. If a new request has arrived,
// that means the old client has expired, and the new one should be used
WiFiClient new_client = server.available();
if (new_client) {
// Read and forward any unread data
tcpToSerial();
// Close existing client
client.stop();
// Make new client the active one
client = new_client;
// Disable Nagle algorithm to decrease latency
//client.setNoDelay(true);
}
if (client.connected() && client.available()) {
// Send any unsent data
//sendTCPBacklog();
tcpToSerial();
}
// Try reading Serial data
int to_read = std::min(Serial.available(), BUF_SIZE);
to_read = 0;
if (to_read) {
Serial.readBytes(serial_in_buf, to_read);
sendTCP(serial_in_buf, to_read);
to_read = std::min(Serial.available(), BUF_SIZE);
}
}
void tcpToSerial() {
if (client.available()) {
// Don't read more than Serial can write at once, to prevent blocking
ssize_t n_to_read = std::min(client.available(), BUF_SIZE);//, Serial.availableForWrite());
if (n_to_read > 0) {
client.read(tcp_in_buffer, n_to_read);
sendTCP(tcp_in_buffer, n_to_read);
}
//sendSerial(tcp_in_buffer, n_to_read);
}
}
int write_cnt = 0;
int write_led_on = 0;
void sendTCP(byte data[], size_t n_bytes) {
size_t to_write = n_bytes;
//to_write = 400;
size_t total_written = 0;
while (client.connected() && to_write) {
//if (!(write_cnt % 2)) {
// digitalWrite(2, write_led_on ? HIGH : LOW);
// write_led_on = !led_on;
//}
//write_cnt++;
//sendTCPBacklog();
size_t written = client.write((const uint8_t*) data + total_written, to_write);
//size_t written = client.write((const uint8_t*) dummy_data + total_written, to_write);
delay(1);
if (written != to_write) {
Serial.println(written);
}
if (written == 0) {
digitalWrite(2, HIGH);
}
total_written += written;
to_write = to_write - written;
to_write = 0;
}
digitalWrite(2, LOW);
}
void sendTCPBacklog() {
struct data_chunk needs_sent = getChunk();
if (needs_sent.length) {
size_t written = client.write((const uint8_t*) needs_sent.data, needs_sent.length);
markConsumed(written);
}
}
//void sendUDP(byte data[], int n_bytes) {
// udp.beginPacket(address, localPort);
// udp.write(data, n_bytes);
// udp.endPacket();
//}
void sendSerial(byte data[], int n_bytes) {
int to_write = n_bytes;
while (to_write) {
int written = Serial.write(data, to_write);
to_write -= written;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment