Commit c17592e8 authored by pengelstein's avatar pengelstein
Browse files

Added serial communication

parent f2203da9
#include "TestMessage.hpp"
#include "stdio.h"
#include <serial/Serial.hpp>
struct Light
{
......@@ -7,9 +8,11 @@ struct Light
char value;
};
TestMessage::TestMessage()
{
int prev_state = 2;
TestMessage::TestMessage(std::shared_ptr<Serial::Serial>& ser)
{
this->ser = ser;
}
TestMessage::~TestMessage()
......@@ -26,11 +29,64 @@ int TestMessage::TreatData(std::vector<char> buffer)
for(auto st : values)
{
Light l = {-1, -1};
//Get the ID of the light
if(st.at(0) >= '0' || st.at(0) <= '9')
l.index = atoi(&(st.at(0)));
if(st.at(3) == 'r' || st.at(3) == 'y' || st.at(3) == 'g')
l.value = st.at(3);
printf("light %d has value %c\n", l.index, l.value);
std::vector<char> buffer;
int state = atoi(&st.at(3));
if(prev_state != state)
{
switch(state)
{
case 0:
buffer.push_back('2');
this->ser->Write(buffer);
break;
case 1:
buffer.push_back('3');
this->ser->Write(buffer);
break;
case 2:
buffer.push_back('5');
this->ser->Write(buffer);
break;
case 3:
buffer.push_back('6');
this->ser->Write(buffer);
break;
}
buffer.clear();
prev_state = state;
}
// switch(st.at(3))
// {
// case 'r':
// //Get the value of the light
// l.value = st.at(3);
// //Send it to the arduino
// buffer.push_back('1');
// this->ser->Write(buffer);
// break;
// case 'y':
// buffer.push_back('2');
// l.value = st.at(3);
// break;
// case 'g':
// buffer.push_back('3');
// l.value = st.at(3);
// break;
// default:
// break;
// }
buffer.clear();
// printf("light %d has value %c\n", l.index, l.value);
}
return 0;
}
......
......@@ -2,19 +2,28 @@
#define TESTMESSAGE_H
#include "thread/Message/IMessage.hpp"
#include <memory>
/**
* Just a first test for custom message handling
*/
namespace Serial
{
class Serial;
};
class TestMessage : public threads::IMessageHandler
{
public:
TestMessage();
TestMessage(std::shared_ptr<Serial::Serial>& ser);
virtual ~TestMessage();
int TreatData(std::vector<char> buffer) override;
std::vector<std::string> split(std::string str, std::string delim);
private:
std::shared_ptr<Serial::Serial> ser;
};
#endif
\ No newline at end of file
......@@ -5,6 +5,9 @@
#include <thread/ThreadPool.hpp>
#include <thread/cross.hpp>
#include <TestMessage.hpp>
#include <serial/Serial.hpp>
#include <serial/SerialConsole.hpp>
#include <serial/SerialReader.hpp>
#include <memory>
#include <signal.h>
......@@ -17,10 +20,15 @@ threads::IMessageHandler *handler;
bool running;
int server_socket;
int threads::Client::nb_client_socket = 0;
std::shared_ptr<Serial::Serial> ser;
std::unique_ptr<Serial::SerialConsole> con;
std::unique_ptr<Serial::SerialReader> rea;
void handle_close(int signal_num)
{
threads::Client::Close(server_socket);
// ser->Close();
server_socket = -1;
running = false;
}
......@@ -39,13 +47,87 @@ BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
}
#endif
int main()
int main(int argc, char **argv)
{
printf("Hello World !\n");
int port = 9999;
std::string protocol = "tcp";
int max_queue = 10;
int max_pool = 5;
std::string device = "/dev/ttyACM1";
int speed = 9600;
int byte_size = 8;
int i = 1;
while(i < argc)
{
if(!strcmp(argv[i], "-p") || !strcmp(argv[i], "--port") )
{
i++;
if(i < argc)
port = atoi(argv[i]);
}
if(!strcmp(argv[i], "-mq") || !strcmp(argv[i], "--max_queue"))
{
i++;
if(i < argc)
max_queue = atoi(argv[i]);
}
if(!strcmp(argv[i], "-pt") || !strcmp(argv[i], "--protocol"))
{
i++;
if(i < argc)
protocol = std::string(argv[i]);
}
if(!strcmp(argv[i], "-mp") || !strcmp(argv[i], "--max_pool"))
{
i++;
if(i < argc)
max_pool = atoi(argv[i]);
}
if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "--device"))
{
i++;
if(i < argc)
device = std::string(argv[i]);
}
if(!strcmp(argv[i], "-s") || !strcmp(argv[i], "--speed"))
{
i++;
if(i < argc)
speed = atoi(argv[i]);
}
if(!strcmp(argv[i], "-b") || !strcmp(argv[i], "--byte_size"))
{
i++;
if(i < argc)
byte_size = atoi(argv[i]);
}
if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
{
printf("TCP threaded server\n");
printf("Usage: ./server [options]\n");
printf("Options:\n");
printf(" -b --byte_size Specify what size is the data transfered via serial\n");
printf(" -d --device Specify which device to open the Serial connection on\n");
printf(" -h --help Display this help.\n");
printf(" -mp --max_pool Specify the cooldown time (in seconds) that a client will have after disconnect\n");
printf(" -mq --max_queue Specify the maximum connection queue that the server can handle\n");
printf(" -p --port Specify the port on which to open the server\n");
printf(" -pt --protocol Specify the protocol to use (tcp is recommended).\n");
printf(" -s --speed Specify the serial communication speed.\n");
exit(0);
}
i++;
}
printf("Launching server using port %d, protocol %s, max_queue %d, max_pool %d\n", port, protocol.c_str(), max_queue, max_pool);
#ifdef __WIN32
WSADATA wsa;
int err = WSAStartup(MAKEWORD(2, 2), &wsa);
......@@ -63,6 +145,14 @@ int main()
#endif
/* register the signal handler for ctrl-c custom action */
signal(SIGINT, handle_close);
/* Create the serial communication and console / read threads */
ser = std::make_shared<Serial::Serial>(device.c_str(), speed, byte_size);
con = std::make_unique<Serial::SerialConsole>(ser);
con->Create();
rea = std::make_unique<Serial::SerialReader>(ser);
rea->Create();
/* Create the server listening socket */
server_socket = threads::SocketThread::CreateServerSocket(port, protocol, max_queue);
......@@ -74,7 +164,7 @@ int main()
delay = new threads::DelayThread();
delay->Create();
pool = new threads::ThreadPool(max_pool);
handler = new TestMessage();
handler = new TestMessage(ser);
running = true;
char flag = 0;
......@@ -116,10 +206,11 @@ int main()
/* End the different other threads and quit */
delay->End();
pool->KillAll();
con->End();
delete delay;
delete pool;
printf("Finished server !\n");
printf("Finished server a!\n");
return 0;
}
\ No newline at end of file
#include "Serial.hpp"
namespace Serial
{
int get_baud(int baud)
{
switch (baud)
{
case 9600:
return B9600;
case 19200:
return B19200;
case 38400:
return B38400;
case 57600:
return B57600;
case 115200:
return B115200;
case 230400:
return B230400;
case 460800:
return B460800;
case 500000:
return B500000;
case 576000:
return B576000;
case 921600:
return B921600;
case 1000000:
return B1000000;
case 1152000:
return B1152000;
case 1500000:
return B1500000;
case 2000000:
return B2000000;
case 2500000:
return B2500000;
case 3000000:
return B3000000;
case 3500000:
return B3500000;
case 4000000:
return B4000000;
default:
return -1;
}
}
Serial::Serial(const char *port, unsigned int baudrate, unsigned int byteSize)
{
this->name = std::string(port);
this->baudrate = get_baud(baudrate);
if(this->baudrate == -1)
{
fprintf(stderr, "[Serial] Got wrong baudrate %d, using 9600.\n", baudrate);
this->baudrate = B9600;
}
switch (byteSize)
{
case 5:
this->byteSize = CS5;
break;
case 6:
this->byteSize = CS6;
break;
case 7:
this->byteSize = CS7;
break;
case 8:
this->byteSize = CS8;
break;
default:
this->byteSize = CS8;
break;
}
this->port = open(this->name.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
struct termios options;
tcgetattr(this->port, &options);
cfsetispeed(&options, this->baudrate);
cfsetospeed(&options, this->baudrate);
options.c_cflag |= (CLOCAL | CREAD);
tcsetattr(this->port, TCSANOW, &options);
options.c_cflag &= ~CSIZE;
options.c_cflag |= this->byteSize;
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
if(this->port == -1)
fprintf(stderr, "[Serial] Failed to create serial to %s.\n", port);
else
fprintf(stdout, "[Serial] Created serial %d\n", this->port);
}
Serial::~Serial()
{
if(this->port != -1)
Close();
}
void Serial::Open()
{
}
void Serial::Close()
{
fprintf(stdout, "[Serial] Closing port %d\n", this->port);
if(this->port != -1)
close(this->port);
this->port = -1;
}
std::vector<char> Serial::Read(int size)
{
std::vector<char> res(size);
int error = -1;
if(this->port != -1)
error = read(this->port, &res[0], size);
if(error == -1)
{
res.resize(0);
return res;
}
else
return res;
}
std::string Serial::ReadLine()
{
std::string res = "";
char current = 0;
int error = -1;
do
{
if(this->port != -1)
error = read(this->port, &current, 1);
if(error != -1)
res += current;
}while(current != '\n');
return res;
}
void Serial::Write(std::vector<char> buffer)
{
if(this->port != -1 && buffer.size() != 0)
write(this->port, buffer.data(), buffer.size());
}
int Serial::Port()
{
return this->port;
}
}
\ No newline at end of file
#ifndef SERIAL_H
#define SERIAL_H
#include <string>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
#include <vector>
namespace Serial
{
class Serial
{
public:
Serial(const char *port, unsigned int baudrate, unsigned int byteSize);
Serial(const char *port, unsigned int baudrate) : Serial(port, baudrate, 8){};
Serial(const char *port) : Serial(port, 9600, 8){};
virtual ~Serial();
void Open();
void Close();
std::vector<char> Read(int size);
std::string ReadLine();
void Write(std::vector<char> buffer);
int Port();
private:
int port;
std::string name;
speed_t baudrate;
unsigned int byteSize;
};
}
#endif
\ No newline at end of file
#include <serial/SerialConsole.hpp>
#include <serial/Serial.hpp>
namespace Serial
{
SerialConsole::SerialConsole(std::shared_ptr<Serial>& ser) : IThread(0)
{
this->ser = ser;
printf("Console using serial %d\n", this->ser->Port());
}
SerialConsole::~SerialConsole()
{
printf("[Serial Console] Closing ...\n");
}
std::string SerialConsole::ToString()
{
return "[Serial Console]";
}
void SerialConsole::Run()
{
while(this->Running())
{
char c;
std::vector<char> input;
do
{
c = getchar();
if(c != '\n')
input.push_back(c);
}while(c != '\n');
if(input.size() != 0)
{
if(strcmp(input.data(), "exit") == 0)
this->_running = false;
else
this->ser->Write(input);
}
if(this->ser->Port() == -1)
this->_running = false;
}
fprintf(stdout, "[SerialConsole] Closing...\n");
}
}
#ifndef SERIALCONSOLE_H
#define SERIALCONSOLE_H
#include <thread/IThread.hpp>
namespace Serial
{
class Serial;
class SerialConsole : public threads::IThread
{
public:
SerialConsole(std::shared_ptr<Serial>& ser);
~SerialConsole();
std::string ToString() override;
void Run() override;
private:
std::shared_ptr<Serial> ser;
};
}
#endif
\ No newline at end of file
#include <serial/SerialReader.hpp>
#include <serial/Serial.hpp>
namespace Serial
{
SerialReader::SerialReader(std::shared_ptr<Serial>& ser) : IThread(0)
{
this->ser = ser;
printf("Reader using serial %d\n", this->ser->Port());
}
SerialReader::~SerialReader()
{
printf("[Serial Reader] Closing ...\n");
}
std::string SerialReader::ToString()
{
return "[Serial Reader]";
}
void SerialReader::Run()
{
while(this->Running())
{
std::string result = ser->ReadLine();
printf("[Serial Reader] %s", result.c_str());
}
}
}
#ifndef SERIALREADER_H
#define SERIALREADER_H
#include <thread/IThread.hpp>
namespace Serial
{
class Serial;
class SerialReader : public threads::IThread
{
public:
SerialReader(std::shared_ptr<Serial>& ser);
~SerialReader();
std::string ToString() override;
void Run() override;
private:
std::shared_ptr<Serial> ser;
};
}
#endif
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment